sql及索引优化

如何通过慢查询日志发现有问题的sql?

  1. 查询次数多且每次查询占用时间长的sql
    通常为pt-query-digest分析的前几个查询

  2. IO大的sql
    注意pt-query-digest分析中的rows examine项

  3. 未命中索引的sql
    注意pt-query-digest分析中rows examine 和 rows send的对比

磁盘IO与预读:磁盘读取数据靠的是机械运动,每次读取数据花费的时间可以分为寻道时间,旋转时间,传输时间三个部分。虽然平常理论上来说没什么压力,

但是数据库如果动辄十万百万乃至千万级数据,显然是个灾难。

了解下mysql的B+树:一种为了减少IO操作快速搜索到数据的数据结构,如下图:


    说明:

蓝色部分磁盘块

黄色部分指针

深蓝色目标数据块
    分析一下查找的过程:

如果要查询数据为29的值:

1.将磁盘一加入到内存中此时发生一次IO,在内存中用二分查找确定29在17和35之间,锁定磁盘块1的P2指针

2.通过磁盘块1的P2指针的磁盘地址把磁盘块3由磁盘加载到内存,发生第二次IO

3. 29在26和30之间,锁定磁盘块3的P2指针,通过指针加载磁盘块8到内存,发生第三次IO,同时内存中做二分查找找到29,结束查询

总结:总计三次IO,真实的情况是,3层的b+树可以表示上百万的数据,如果上百万的数据查找只需要三次IO,性能提高将是巨大的,如果没有索引,

每个数据项都要发生一次IO,那么总共需要百万次的IO,显然成本非常非常高。

解释下什么叫二分法:其实就是一种通过不断排除不可能的东西,来最终找到需要的东西的一种方法,所以可以理解成排除法。之所以叫二分,是因为

每次排除都把所有的情况分为“可能”和不可能两种,然后抛弃所有“不可能”的情况。

优化sql实际上主要目的是为了减少IO操作:
1.如果想在mysql配置方面减少IO的操作:尽可能使用缓存,减少读写对数据库的随机IO的请求,同时减少写的随机IO的随时发生,利用各种buffer去缓存。

2.创建索引:合理的索引是为了少量IO操作达到数据的获取。

建立索引的几大原则:
1.在where 从句,group by从句,on从句中出现的列

2.最左前缀匹配,非常重要的原则,mysql会一直向左匹配直到遇到范围查询(>,<,between,like)就停止匹配
eg:a=1 and b=2 and c=3 and d=4   索引  add index (a,b,c,d)  这样创建d是用不到索引的
eg:a=1 and b=2 and c=3 and d=4   索引  add index(a,b,d,c) 这样创建则都可以用到,a,b,d的顺序可以任意调整

3.离散度大的列放到联合索引的前面

计算离散度的公式是count(distinct col)/count(*),表示字段不重复的比例,比例越大我们扫描的记录数越少。

select * from payment where staff_id=2 and customer_id=584;

是index(sftaff_id,customer_id)好?还是index(customer_id,staff_id)?
    由于customer_id的离散度更大,所以应该使用index(customer_id,staff_id)

4.索引列不能参与计算,保持列干净
    索引列不能参与计算,保持列干净,在where语句中索引字段不要使用函数,进行检索的时候需要把所有元素都应用函数才能比较,先人成本太大。

5.索引字段越小越好
    使用短索引,如果对字符串列进行索引,应该指定一个前缀长度,可节省大量索引空间,提升查询速度。

6.尽量的扩展索引,不要新建索引。

说了这么多索引的优点但是索引也是有负面的:

  1. 每个额外的索引都要占用额外的磁盘空间,并降低写操作的性能

2.在修改表的内容时,索引必须进行更新,有时可能需要重构,因此,所花的时间越长。

什么叫做好的索引:

  1. 查询频繁(业务逻辑决定)

  2. 区分度高

  3. 长度小(与区分度保持一个平衡就是一个最优的效果)

  4. 尽量能覆盖常用查询字段(并不表示所有字段都建立索引)

sql及索引优化

如何通过慢查询日志发现有问题的sql?

  1. 查询次数多且每次查询占用时间长的sql
    通常为pt-query-digest分析的前几个查询

  2. IO大的sql
    注意pt-query-digest分析中的rows examine项

  3. 未命中索引的sql
    注意pt-query-digest分析中rows examine 和 rows send的对比

磁盘IO与预读:磁盘读取数据靠的是机械运动,每次读取数据花费的时间可以分为寻道时间,旋转时间,传输时间三个部分。虽然平常理论上来说没什么压力,

但是数据库如果动辄十万百万乃至千万级数据,显然是个灾难。

了解下mysql的B+树:一种为了减少IO操作快速搜索到数据的数据结构,如下图:

说明:

蓝色部分磁盘块

黄色部分指针

深蓝色目标数据块
    分析一下查找的过程:

如果要查询数据为29的值:

1.将磁盘一加入到内存中此时发生一次IO,在内存中用二分查找确定29在17和35之间,锁定磁盘块1的P2指针

2.通过磁盘块1的P2指针的磁盘地址把磁盘块3由磁盘加载到内存,发生第二次IO

3. 29在26和30之间,锁定磁盘块3的P2指针,通过指针加载磁盘块8到内存,发生第三次IO,同时内存中做二分查找找到29,结束查询

总结:总计三次IO,真实的情况是,3层的b+树可以表示上百万的数据,如果上百万的数据查找只需要三次IO,性能提高将是巨大的,如果没有索引,

每个数据项都要发生一次IO,那么总共需要百万次的IO,显然成本非常非常高。

解释下什么叫二分法:其实就是一种通过不断排除不可能的东西,来最终找到需要的东西的一种方法,所以可以理解成排除法。之所以叫二分,是因为

每次排除都把所有的情况分为“可能”和不可能两种,然后抛弃所有“不可能”的情况。

优化sql实际上主要目的是为了减少IO操作:
1.如果想在mysql配置方面减少IO的操作:尽可能使用缓存,减少读写对数据库的随机IO的请求,同时减少写的随机IO的随时发生,利用各种buffer去缓存。

2.创建索引:合理的索引是为了少量IO操作达到数据的获取。

建立索引的几大原则:
1.在where 从句,group by从句,on从句中出现的列

2.最左前缀匹配,非常重要的原则,mysql会一直向左匹配直到遇到范围查询(>,<,between,like)就停止匹配
eg:a=1 and b=2 and c=3 and d=4   索引  add index (a,b,c,d)  这样创建d是用不到索引的
eg:a=1 and b=2 and c=3 and d=4   索引  add index(a,b,d,c) 这样创建则都可以用到,a,b,d的顺序可以任意调整

3.离散度大的列放到联合索引的前面

计算离散度的公式是count(distinct col)/count(*),表示字段不重复的比例,比例越大我们扫描的记录数越少。

select * from payment where staff_id=2 and customer_id=584;

是index(sftaff_id,customer_id)好?还是index(customer_id,staff_id)?
    由于customer_id的离散度更大,所以应该使用index(customer_id,staff_id)

4.索引列不能参与计算,保持列干净
    索引列不能参与计算,保持列干净,在where语句中索引字段不要使用函数,进行检索的时候需要把所有元素都应用函数才能比较,先人成本太大。

5.索引字段越小越好
    使用短索引,如果对字符串列进行索引,应该指定一个前缀长度,可节省大量索引空间,提升查询速度。

6.尽量的扩展索引,不要新建索引。

说了这么多索引的优点但是索引也是有负面的:

  1. 每个额外的索引都要占用额外的磁盘空间,并降低写操作的性能

2.在修改表的内容时,索引必须进行更新,有时可能需要重构,因此,所花的时间越长。

什么叫做好的索引:

  1. 查询频繁(业务逻辑决定)

  2. 区分度高

  3. 长度小(与区分度保持一个平衡就是一个最优的效果)

  4. 尽量能覆盖常用查询字段(并不表示所有字段都建立索引)

性能优化之mysql索引优化的更多相关文章

  1. MySQL性能优化,MySQL索引优化,order by优化,explain优化

    前言 今天我们来讲讲如何优化MySQL的性能,主要从索引方面优化.下期文章讲讲MySQL慢查询日志,我们是依据慢查询日志来判断哪条SQL语句有问题,然后在进行优化,敬请期待MySQL慢查询日志篇 建表 ...

  2. MYSQL索引优化思维导图

    有关索引的优化.MYSQL索引优化     文章来源:刘俊涛的博客 地址:http://www.cnblogs.com/lovebing

  3. Mysql 索引优化分析

    MySQL索引优化分析 为什么你写的sql查询慢?为什么你建的索引常失效?通过本章内容,你将学会MySQL性能下降的原因,索引的简介,索引创建的原则,explain命令的使用,以及explain输出字 ...

  4. 知识点:Mysql 索引优化实战(3)

    知识点:Mysql 索引原理完全手册(1) 知识点:Mysql 索引原理完全手册(2) 知识点:Mysql 索引优化实战(3) 知识点:Mysql 数据库索引优化实战(4) 索引原理知识回顾 索引的性 ...

  5. MySQL索引优化步骤总结

    在项目使用mysql过程中,随着系统的运行,发现一些慢查询,在这里总结一下mysql索引优化步骤 1.开发过程优化 开发过程中对业务表中查询sql分析sql执行计划(尤其是业务流水表),主要是查看sq ...

  6. MySQL索引优化看这篇文章就够了!

    阅读本文大概需要 5 分钟. 来源:cnblogs.com/songwenjie/p/9410009.html 本文主要讨论MySQL索引的部分知识.将会从MySQL索引基础.索引优化实战和数据库索引 ...

  7. mysql索引优化比普通查询速度快多少

    mysql索引优化比普通查询速度快多少 一.总结 一句话总结:普通查询全表查询,速度较慢,索引优化的话拿空间换时间,一针见血,所以速度要快很多. 索引优化快很多 空间换时间 1.软件层面优化数据库查询 ...

  8. mySql索引优化分析

    MySQL索引优化分析 为什么你写的sql查询慢?为什么你建的索引常失效?通过本章内容,你将学会MySQL性能下降的原因,索引的简介,索引创建的原则,explain命令的使用,以及explain输出字 ...

  9. 讲真,MySQL索引优化看这篇文章就够了

    本文主要讨论MySQL索引的部分知识.将会从MySQL索引基础.索引优化实战和数据库索引背后的数据结构三部分相关内容,下面一一展开. 一.MySQL——索引基础 首先,我们将从索引基础开始介绍一下什么 ...

随机推荐

  1. 用Qt写了一个qq客户端,采用webqq协议,发出来和大家分享一下---大神请无视

    首先做以下声明: 本程序基于腾讯公司的webqq协议开发,所有相关版权归腾讯公司所有.此程序只用于技术交流和学习,不得用于其他方面. ---开发者:雨后星辰,转载请注明出处:http://www.cn ...

  2. Reverse a String

    题目: 翻转字符串 先把字符串转化成数组,再借助数组的reverse方法翻转数组顺序,最后把数组转化成字符串. 你的结果必须得是一个字符串 这是一些对你有帮助的资源: Global String Ob ...

  3. log4cpp安装

    body, table{font-family: 微软雅黑; font-size: 10pt} table{border-collapse: collapse; border: solid gray; ...

  4. Week14《Java程序设计》第14次作业总结

    Week14<Java程序设计>第14次作业总结 1. 本周学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结与数据库相关内容. 2. 使用数据库技术改造你的系统 2.1 简述如何 ...

  5. php远程文件包含截断问题

    今天在学习<白帽子讲web安全>一书是,提到一个php远程文件包含漏洞 可以从攻击者服务器中的一个写好的攻击脚本中远程执行命令 服务器中有漏洞的页面代码为: #test.php#error ...

  6. Linux输入输出管理

      一.系统输入输出的理解 运行一个程序时,需要从某个位置读取输入信息,然后CPU处理,最后将输出 显示在屏幕或文件中:其中,某个位置相当于输入设备,屏幕或文件为输出设备. 标准输入:stdin,默认 ...

  7. 【PL/SQL编程】条件语句

    1. if...then语句 if <condition_expression> then plsql_sentence; end if; declare -- Local variabl ...

  8. Git 中文教程

    以下内容转载自:http://www.open-open.com/lib/view/open1328928294702.html Git是一个分布式的版本控制工具,本篇文章从介绍Git开始,重点 在于 ...

  9. phpcms v9取消验证码

    phpcms/modules/admin/index.php// $code = isset($_POST['code']) && trim($_POST['code']) ? tri ...

  10. 用户空间与内核驱动的交互过程 — ioctl

    在Linux内核模块的开发过程中,经常涉及到运行在用户空间上的应用程序与内核模块进行交互,ioctl系统调用是常用的一种方式.本文并不涉及vlan的具体原理,仅通过vconfig与vlan内核模块进行 ...