MySQL学习笔记10

106 阅读2分钟

排序与索引

MySQL有两种方式可以生成有序的结果:通过排序操作;或者按索引顺序扫描。

只有当索引的列顺序ORDER BY子句的顺序完全一致,并且所有列的排序方向(倒序或正序)都一样时,MySQL才能够使用索引来对结果做排序。

如果查询需要关联多张表,则只有当ORDER BY子句引用的字段全部为第一个表时,才能使用索引做排序。ORDER BY子句和查找型查询的限制是一样的:需要满足索引的最左前缀的要求;否则,MySQL都需要执行排序操作,而无法利用索引排序。

有一种情况下ORDER BY子句可以不满足索引的最左前缀的要求,就是前导列为常量的时候。如果WHERE子句或者JOIN子句中对这些列指定了常量,就可以“弥补”索引的不足。

一些创建索引的技巧

假设有组合索引(sex,country),如果碰到where语句中不需要包含sex,为了让组合索引生效则可以在where语句中加上 AND SEX IN('m','f')来让MySQL选择该索引。这样写并不会过滤任何行,和没有这个条件时返回的结果相同。但是必须加上这个列的条件,MySQL才能够匹配索引的最左前缀。

尽可能将需要做范围查询的列放到索引的后面,以便优化器能使用尽可能多的索引列。

SELECT actor_id FROM sakila.actor
        -> WHERE actor_id > 45\G

SELECT actor_id FROM sakila.actor
        -> WHERE actor_id IN(1, 4, 99)\G

第一个查询是范围查询,对于范围条件查询,MySQL无法再使用范围列后面的其他索引列了。

第二个查询(in ...))就是**多个等值条件查询。**对于“多个等值条件查询”则没有这个限制。

减少索引和数据的碎片

有三种类型的数据碎片:

行碎片(Row fragmentation)

行间碎片(Intra-row fragmentation)

剩余空间碎片(Free space fragmentation)

可以通过执行OPTIMIZE TABLE或者导出再导入的方式来重新整理数据。这对多数存储引擎都是有效的。