一条SQL语句执行很慢的原因(面试常问)
程序员文章站
2022-03-26 14:48:28
1:面试Java被问到sql语句执行很慢的原因好几次了,下面来做一个总结。sql语句执行很慢的一般分一直很慢和偶尔很慢。2. A:Sql语句一阵子很慢a:没有对表中字段建立索引,全局搜索当然很慢b:建立了索引,但是在执行sql语句的时候却没有命中索引。例如:一个student表,里面有id,name,age,score等四个字段,id作为主键,name和age上也加了索引,但是你的sql语句确却是:select* from student 这显然是没有命中索引,这也是在sql优化中需要做到....
- 面试Java问到sql语句执行很慢的原因好几次了,下面来做一个总结。sql语句执行很慢的一般分一直很慢和偶尔很慢。
2. A:Sql语句一阵子很慢
- a:没有对表中字段建立索引,全局搜索当然很慢
- b:建立了索引,但是在执行sql语句的时候却没有命中索引。例如:一个student表,里面有id,name,age,score等四个字段,id作为主键,name和age上也加了索引,但是你的sql语句确却是:select* from student 这显然是没有命中索引,这也是在sql优化中需要做到的,尽量不要用select *,避免无法使用聚合索引;还有就是你的sql语句是:select name,age where age-1>10 你以为是命中索引了吗?其实也没有,musql在现在版本使用的InooDB,通俗点说,它只认识age索引,它不会把age-1>10自动转化为age>11。还有就是,一些聚合函数的使用,也可能导致无法命中索引。
- c:建立了索引,也命中了索引,但还是执行的很慢。这个就很玄幻了,对于现在的mysql数据库,InooDB的数据文件就是一个索引文件,底层是B树中的B+树,key值存储的是数据库的主键,这个数据文件是主索引,其他的索引都是辅助索引。例如b中所说的name,age都是辅助索引,id是主索引。当你的sql语句是:select name ,age where age>10 ,这条语句命中了索引,但如果执行很慢,那一定是走了全局搜索。为什么?辅助索引中存储的是主键的值,一般如果走辅助索引的话,会先在辅助索引中找到主键索引,再根据主键索引去进行二分法搜索,所以当系统判断走两次索引搜索和走全局搜索时用的时间是差不多的,显然,它是会走全局搜索的。如何判断两次索引搜索的时间?这与数据库本身有关系,如果你的数据库表中的不同值越多,那么区分度越高,数据库就是通过随机采样来判断的。如果不碰巧,抽到的几条数据恰好重复率很高,那么,区分度很低,走全局索引了。
6. B:Sql语句偶尔很慢
- a:拿不到锁:InonnDB支持表级锁和行级锁,默认是行级锁,如果一个表被加了排它锁(可供多个读,却最多只能有一个在写),且正在增删数据。另外的一个事务再去访问这个表进行增删的时候,显然要等到第一个事务执行完释放锁才行,处于等待中。
- b:数据库刷脏页。一般,执行sql语句进行增删改的时候,会先把修改的数据记录到redo log(这里不细说什么是redo log了)中,等到数据库系统认为空闲的时候再将redo log中的数据刷到磁盘中,这就叫做刷脏页。那么,不巧,此刻你在执行sql语句的时候,系统认为空闲了,在刷脏页。没办法。
注意:博主刚从学校出来,意见浅薄,文中也吸收了很多他人优秀经验。不足之处,以后看到了或者遇到了补充。如果有技术大大恰巧路过此地,也可以写下更多想法,欢迎批评改正,谢谢。
本文地址:https://blog.csdn.net/qq_40230026/article/details/107168592
下一篇: 模板参数的“右值引用”是转发引用