查询 作为数据库语言中最常见的DML操作之一,在运用时,我们常会关注其运行速度。
通过建立索引,可以加快数据查询的效率,但是同样也会出现查询慢的问题。
这就需要具体分析数据查询慢的具体原因了。
以下以MySQL为例
有索引,查询速度慢
查询条件为空
当进行查询时,where条件中出现了判断是否为null的情况,导致数据库的引擎不会使用索引,而进行全表扫描,这样的查询就会变得很慢。
字段类型不匹配导致的索引失效
进行 查询的时候,where 条件字段类型与实际表中字段类型不匹配的时候,Mysql 会进行隐式的数据类型转换,而类型转换会使用到内置函数,导致在进行数据查询的时候并没有使用索引。我们可以使用 explain 命令查看 查询语句使用索引情况。
被索引字段使用了表达式计算
在 where 中条件使用了条件表达式的时候,数据表中的索引就失效了,实际是因为 Mysql 需要将索引字段取出来之后再进行表达式的条件判断,因而进行了全表扫描,导致索引失效。
被索引字段使用了内置函数
索引字段实际上是依赖于整个 B+索引树的遍历,而索引树的遍历又依赖于索引树底层叶子节点的有序性。索引保存的是索引列的原始值,如果经过函数计算,Mysql 的解释器无法判断计算后的索引在原来的索引树上是否可以被索引到,因此它就直接放弃使用索引查询了。
like 中使用了 %X 模糊匹配
使用左模糊匹配以及左右模糊匹配都会导致索引失效,但是使用右模糊匹配,还是可以走索引查询的。
原因:索引字段依赖B+索引树的遍历。由于 B+树按照索引值进行排序的,实际是按照最左前缀进行比较,而使用了 %作为最左前缀,Mysql 无法判断其有序性,因此只能进行全表扫描查询。
索引字段不是联合索引字段的最左字段
如果数据库表中有联合索引的话,在查询语句中使用的索引字段又不是联合索引的最左字段,那么就会导致索引失效。
原因:在 Mysql 中的索引检索是遵循最左匹配原则的,同时 B+索引树的叶子节点的有序性也是建立在最左匹配原则之上。
or 分割的条件,如果 or 左边的条件存在索引,而右边的条件没有索引,不走索引
因为 OR 的含义就是两个只要满足一个即可,因此只有一个条件列进行了索引是没有意义的,只要有条件列没有进行索引,就会进行全表扫描,因此索引的条件列也会失效。
in、not in 可能会导致索引失效
这里需要说明的是使用 in 以及 not in 走不走索引,实际和 Mysql 的版本以及表中的数据量有关系,在 8.0 之后的版本是走索引的。
查询速度慢的原因
包括上述“有索引,查询速度慢”所有情况。还有以下原因:
附参考资料: