本文只但从数据库自己来看查询慢的可能因素,至于内存不够、网速较慢不属于本文讨论范畴。html
本文内容参考自公众号文章:mysql
腾讯面试:一条SQL语句执行得很慢的缘由有哪些?---不看后悔系列面试
我对公众号中的内容做本身的梳理总结sql
开始数据库
首先要分类讨论一下,这条查询语句是在偶尔的状况下查询效率慢,仍是一直都存在查询效率慢的问题。mysql优化
对于第一种状况,可能查询语句自己没有问题,是数据库遇到了其余问题;函数
对于第二种状况,应该是查询语句出了问题,须要优化优化
当对数据库进行插入或者更新操做时,数据库会马上将内存的数据页上的信息更新,可是不会马上将将更新的数据存到磁盘上,而是先保存到redo log中,等合适的时机在将redo log的信息存储到磁盘上spa
针对这种内存中的数据页和磁盘上的数据不一样的状况咱们将内存中的数据页称为“脏”页,而内存中和磁盘上数据相同的状况则称为“干净”页。3d
刷新“脏”页时,系统会暂停其余的操做,全身心的将数据存到磁盘中,就会致使日常正常执行的mysql语句变慢
case1:redo log装满时
case2:内存不够用时
case3:mysql认为系统空闲时
case4:mysql正常关闭时
能够用show processlist命令查看一下语句执行的状态,查看要查询的数据是否被锁住
查看是否查询了没必要要的行与列,避免用select * from table这样的语句
当数据量很大时,若没有用索引采用全表索引是很耗费时间的。而这里没有用到索引由能够分多钟状况
引发索引失效的可能缘由
1)在索引列上用了内置函数或者其余+-*/运算
2)用通配符开头
3)多列索引违背最佳最匹配原则
4)or操做符容器形成索引失效,除非or的每一个操做列都有索引
5)字符串不加单引号
系统选错索引实际上是索引失效的一种形式,可是因为涉及到的知识点较多,因此单独拿出来分析。
系统选错索引致使索引失效时系统将全表扫描与用索引要扫描的行数进行比较,如果以为运用索引反而要复杂,则系统就会放弃索引采用全表扫描的方式。
那么何时会出现运用索引反而比全表扫描效率更低的状况呢?
首先咱们都知道主键索引保存的是整行数据,而非主键索引保存的是主键的值。因此运用非主键索引时要先定位到知足条件的行的主键值,在由主键值拿到整行数据的信息,要通过两次索引的过程。
极端状况下,当索引寻找的数据条件全表都知足时,则此时索引寻找相比于全表扫描反而多了一系列索引过程。
因此系统在判断是否须要应用索引时会先判断若是运用索引大体须要扫描多少行,若是系统预测要扫描的行数不少,则系统会选择放弃索引采起全表扫描的方式。
系统如何判断运用索引须要扫描的行数?这就须要用到索引的区分度。索引的区分度又称为基数,一个索引上不一样的值越多,意味着出现相同数值的索引越少,意味着索引的区分度越高。
区分度越高,则知足索引查询条件的数据就越少,则系统预测扫描的函数很少。
那么索引的区分度又是如何得来的呢?
采样。系统经过采样的方式来推测索引的区分度。既然是采样则就会有偏差,若是你想避免这种偏差,不想要系统进行这种它认为的人性化的选择方式,你能够强制运用索引
select * from t index(a) where c>100 and c<1000;
你也可用下面的第一行命令查看索引的基数,若是基数和实际不符合的话你也可用第二行命令让系统从新采样计算索引基数
1 show index from t; 2 analyze table t;
能够用explain+SQL查询语句来查看SQL语句的执行过程,查看是否用到了预期索引
explain命令能够参考个人另外一篇博文mysql优化一之查询优化