如何优化sql &最左匹配原则&索引是越多越好么?

由索引衍生出来的问题,以mysql为例
  • 一 如何定位并优化慢查询Sql
  • 二 联合索引的最左匹配原则的成因
  • 三 索引是建立得越多越好吗
一 如何定位并优化慢查询Sql,大致思路
  • 根据慢日志定位慢查询sql (定位sql)
  • 使用explain等工具分析sql (分析sql)
  • 修改sql或者尽量让sql走索引(优化sql)

根据慢日志定位慢查询sql

使用explain等工具分析sql

关于explain关键字段分析

  • type(mysql找到数据行的方式),最后两个是全盘扫描,出现最后两个一般需要优化
    查询性能从最优到最差排序为system>const>eq_ref>ref>fulltext>ref_or_null>index merge>unique_subquery>index_subquery>range>index>all

system最快:不进行磁盘IO
const:PK或者unique上的等值查询
eq_ref:PK或者unique上的join查询,等值匹配,对于前表的每一行(row),后表只有一行命中
ref:非唯一索引,等值匹配,可能有多行命中
range:索引上的范围扫描,例如:between/in/>
index:索引上的全集扫描,例如:InnoDB的count

  • extra(没有type直观,但信息更详细,可以辅助我们了解语句执行方式)
可以用force index(indexName)测试不同索引的查询效率进行优化
调优的方式
  • 尽量使用索引进行查询(可以更改为使用索引查询,或者原查询加索引)
  • 详见MySQL数据库优化的八种方式

二 联合索引最左匹配原则
设置联合索引

联合索引最左匹配原则概念
1.最左前缀匹配原则,非常重要的原则,我们在建立索引的时候,如果是联合索引.举个例子 比如 你一个表 第一个字段是id 第二个字段是 name 第三个字段是age,(id,name,age),三个字段都有索引,就是先按id排序,然后在第一个前提下 再对name排序,再对 age排序,都是在前一个索引排好序的前提下、如果你是一上来就是直接第三个索引范围查询就gg,如果你先第一个索引查 and 第二个索引范围查询,那就是可以的,必须要按顺序来,不能跳.

比如五个人 名字为 A A A B B age分别为 2 3 4 1 2
按名字和age建索引
先是 (A 2) (A 3) (A 4) (B 1) (B 2)
再按照age排序 但是A索引大前提不变 也就是A 在B前面
现在我age规则是 从大到小
(A 4) (A 3) (A 2) (B 2) (B 1)
最后age并不是从大到小
二是内部从大到小(同A的情况下再利用后一个索引排序)
其实这里类似于一种稳定性

2.如果遇到范围查询(>、<、between、like)会中断使用索引,而=和in可以乱序,比如a=1 and b=2 and c=3建立(a,b,c)索引可以任意顺序,mysql的查询优化器会帮你优化成索引可以识别的形式

最左匹配原则成因---B+树建立索引时候的排序问题
当b+树的数据项是复合的数据结构,比如(id,name,age)的时候,b+数是按照从左到右的顺序来建立搜索树的.比如当(2,张三,23)这样的数据来检索的时候,b+树会优先比较id来确定下一步的所搜方向,如果id相同再依次比较name和age,最后得到检索的数据;但当(2,23)这样的没有name的数据来的时候,b+树就不知道下一步该查哪个节点,因为建立搜索树的时候name就是第一个比较因子,必须要先根据name来搜索才能知道下一步去哪里查询。比如当(2,23)这样的数据来检索时,b+树可以用id来指定搜索方向,但下一个字段name的缺失,所以只能把id等于2的数据都找到,然后再匹配年龄是23的数据了, 这个是非常重要的性质,即索引的最左匹配特性。

成因来自https://blog.csdn.net/u013164931/article/details/82386555

数据库语句的常用优化

1、使用连接(JOIN)来代替子查询(Sub-Queries)
连接(JOIN)之所以更有效率一些,是因为MySQL不需要在内存中创建临时表来完成这个逻辑上的需要两个步骤的查询工作。
2、使用联合(UNION)来代替手动创建的临时表
3、对热点数据简历索引
4、不使用NOT IN和<>操作
IN,NOT IN和<>操作都不会使用索引将进行全表扫描。NOT IN可以NOT EXISTS代替,id<>3则可使用id>3 or id<3来代替。
5.对于多张大数据量(这里几百条就算大了)的表JOIN,要先分页再JOIN,否则逻辑读会很高,性能很差
6.不要使用 select * from t ,用具体的字段列表代替“*”,不要返回用不到的任何字段
更多优化语句可以看,后面的链接https://blog.csdn.net/zhangbijun1230/article/details/81608252

索引是越多越好么?
  • 数据量小的表不需要建立索引,建立会增加额外的索引开销

  • 数据变更需要维护索引,因此更多的索引意味着更多的维护成本,因为我们对数据操作时候通常底层涉及到索引结构的一些分裂和合并,详情B+树索引结点的分裂以及合并

  • 更多的索引意味着也需要更多的空间

你可能感兴趣的:(如何优化sql &最左匹配原则&索引是越多越好么?)