mysql查询效率

1.参考

MySQL实战—— Limit与Order by 对查询效率的巨大影响

https://blog.csdn.net/zhibo_lv/article/details/117846795

视频:尚硅谷MySQL数据库高级(bilibili收藏)

2.索引

2.1引入

2.1.1SQL执行慢的原因

1)Sql写的烂

2)索引没建好

3)表设计不好,导致join过多

4)服务器调优和参数设置不合理

2.1.2.sql写的顺序和机读顺序

1)写的顺序

2)机读顺序

2.2基本概念

1)索引是帮助mysql快速查找数据的数据结构

2)不真删除数据,而往往采用假删除的原因:

a.保留数据,业务不用,可以做分析用

b.频繁删除数据,会导致索引失效

c.删除数据会导致出现间隙,引发间隙锁,降低执行效率

3)索引本身也很大,往往以文件的形式存在磁盘

4)索引的数据结构是BTree结构(多路搜索树),其中,聚集索引、次要所以、唯一索引、复合索引、覆盖索引用的是B+树

2.3索引的优势劣势

1)优势:

提高了查询效率,减少了数据库IO成本

提高了排序效率,降低了CPU消耗

提高并发能力,mysql的InnoDB引擎可以添加行锁,行锁是基于索引的,因此可以提高并发能力

2)劣势

索引也是一张表,保存了主键、索引字段,并指向实体表记录(指针),占用空间;

索引虽然提高查询效率,但是会降低更新表的速度,因为维护数据的同时也要维护对应索引

2.4索引的分类

1)单值索引:只包含一个列的索引

2)唯一索引:索引字段的值不重复,但允许空值

3)复合索引:包含多个列

2.5索引的结构与检索原理


1)3层b+树可以表示上百万条数据,定位到数据只发生3次IO,不需要每条数据都IO,性能极大提升

2)真实数据存在叶子节点,如3、5、9、10都是真实数据

3)非叶子节点不存真实数据,只存某种导向信息,如17、35不真实存在于数据表中

2.6适合、不适合建索引的条件

1)适合的:

主键自动建唯一索引

频繁作为查询条件的字段

外键建立索引

2)不适合的

频繁更新的字段

where用不到的字段

高并发下单值索引还是复合索引?---复合索引更好

经常增删改的表不建索引

数据量少的表不建索引

字段值少的(例如枚举)不建索引

2.7单表、双表、三表建索引

单表:在where和orderby的字段上建索引

双表:左联在右表关联字段上建索引,右联在左表关联字段上建索引

三表:同双表经验

2.8建索引注意点:

1)全值匹配最爱:复合索引,查询条件字段与索引字段、顺序都对应;

2)最左匹配原则:(参考:https://blog.csdn.net/zhouchen1998/article/details/124672991)

index_abc:(a, b, c)  //相当于同时有了(a)、(a, b)、(a, b, c)索引

select * from table where a = 'aa' and b ='bb' and c='cc';  //最好,全值匹配

select * from table where c='cc' and b='bb' and a='aa';  //也生效,因为查询优化器会调整顺序,仅有==和in可以顺序随意

select * from table where c='cc' and b='bb';  //索引失效,最左匹配不上

3)不在索引列上做做任何操作(计算、函数、(自动or手动)类型转换),会导致索引失效

4)索引,不能使用查询条件为范围的后面的字段

select * from table where a='aa' and b>'bb' and c='cc';  //c失效,b是范围查找后面就失效,大于、小于、between、in、like

                                                                                               //a用于查找,b用于排序,c失效

5)尽量使用覆盖索引(索引字段全覆盖查询字段),减少select*,

select a,c,b from table where c='cc' and b='bb';  //索引生效,因为查询内容覆盖索引,查找索引树,而不是全表搜索

6)使用!=、>、<,会导致索引失效,全表查询

7)is null、is not null也无法使用索引

8)like百分号加右边

select * from table where a like '%aa%';  //索引失效

select * from table where a like '%aa';  //索引失效

select * from table where a like 'aa%';  //可以使用索引

9)like百分号不能加右边,但是还不想索引失效

select a,b,c  from table where a like '%aa%';  //全覆盖索引,使用索引

10)字符串不加单引号,索引失效

select * from table where a = 'aa';  //索引生效

select * from table where a = aa;  //能查出来,优化器执行类型转换。索引失效,隐式的类型转换导致

11)少用or,用它会导致索引失效

select * from table where a = 'aa1' or 'aa2';   //索引失效

3.sql查询优化

3.1分析步骤

1)观察、测试,至少跑1天,看看生产的慢sql情况

2.开启慢查询日志,并设置阙值,比如执行超过5s的就是慢查询,并把它抓取出来

3.explain+慢sql分析

4.show profile  //查看sql在mysql服务器里的执行细节和生命周期情况

5.运维经理orDBA,进行sql数据库服务器的参数调优

3.2查询优化

3.2.1小表驱动大表:减少io连接次数,io连接也消耗性能

1)类比解释:外层次数少,内层次数多

for(i=0;i<5;...){

    for(j=0;j<1000;...){}

}

2)in和exist:exist是in的变种写法,一般用in,变种可以贴合小表驱动大表原则

select * from A where bid in (select id from B)  //先执行子查询,如果B数据量小,此时用in非常合适

select * from A where exist(select '随便' from B where B.id=A.bid)  //将主查询的数据放到子查询中做验证,先执行煮茶询,如果A中数据量小,此时用exist非常合适

3.2.2使用索引优化order by

1)mysql支持两种方式的排序,index和filesort;index效率高,它指mysql扫描索引完成排序;filesort效率低

2)order by 满足两种情况,使用index排序:index_abc:(a, b, c)

a)order by 后的字段遵循最左匹配原则

select * from table where a>'aa' order by a,b,c;  //using index,order by遵循最左匹配

select * from table where a>'aa' order by c,b;  //using filesort,order by不遵循最左匹配

b)where 与order by条件列组合满足最左匹配原则

select * from table where a='aa' order by b,c;  //using index,where与order by组合遵循最左匹配

select * from table where a>'aa' order by b,c;  //using filesort

select * from table where a='aa' and b='bb' order by c;  //using index

select * from table where a='aa' and b>'bb' order by b,c;  //using index,where里面b>,但是order by续上了,也行


3.2.2使用索引优化group by

group by实质是先排序后分组,适用于order by的以上原则,同样适用于group by

3.2.3慢查询日志


1)默认关闭,需要主动开启,开启慢查询日志会消耗数据库性能

2)可以使用分析工具

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容