MySQL 索引分类
MySQL 中的索引主要用于加快数据检索速度。常见的索引类型包括:
-
主键索引(Primary Key Index)
- 每张表只能有一个主键索引。
- 主键列的值必须唯一且不能为 NULL。
- 主键索引通常是聚簇索引(Clustered Index),即数据行的物理存储顺序与索引顺序一致。
-
唯一索引(Unique Index)
- 唯一索引列的值必须唯一,但允许有 NULL 值。
- 一张表可以有多个唯一索引。
-
普通索引(Normal Index)
- 最基本的索引类型,没有唯一性约束。
- 适用于频繁查询但不需要唯一性的列。
-
全文索引(Fulltext Index)
- 用于全文搜索,适用于
CHAR、VARCHAR和TEXT类型的列。 - 主要用于
MATCH AGAINST查询。
- 用于全文搜索,适用于
-
组合索引(Composite Index)
- 在多个列上创建的索引。
- 查询时遵循最左前缀原则(Leftmost Prefix Principle),即查询条件必须包含组合索引的最左列,否则索引可能失效。
-
前缀索引(Prefix Index)
- 对列的前缀部分创建索引,适用于较长的字符串列。
- 可以节省索引空间,但可能会影响查询精度。
-
空间索引(Spatial Index)
- 用于地理空间数据类型(如
GEOMETRY)。 - 支持空间查询操作。
- 用于地理空间数据类型(如
索引失效的常见场景
-
未使用最左前缀原则
- 对于组合索引,查询条件必须包含索引的最左列,否则索引失效。
- 例如,组合索引为
(A, B, C),查询条件为B = 1 AND C = 2,索引将失效。
-
使用函数或表达式
- 在查询条件中对索引列使用函数或表达式,索引将失效。
- 例如,
WHERE YEAR(create_time) = 2023,索引create_time将失效。
-
类型转换
- 查询条件中的数据类型与索引列的数据类型不一致,导致索引失效。
- 例如,索引列为
VARCHAR,查询条件为WHERE column = 123,索引将失效。
-
使用
OR条件- 查询条件中使用
OR连接多个条件,且其中一个条件未使用索引,索引将失效。 - 例如,
WHERE A = 1 OR B = 2,如果B列没有索引,索引A将失效。
- 查询条件中使用
-
LIKE查询以通配符开头- 使用
LIKE查询时,如果通配符%或_出现在开头,索引将失效。 - 例如,
WHERE column LIKE '%abc',索引将失效。
- 使用
-
NOT、!=、<>操作符- 使用
NOT、!=或<>操作符时,索引可能失效。 - 例如,
WHERE column != 1,索引将失效。
- 使用
-
数据分布不均匀
- 如果索引列的数据分布非常不均匀(如大部分值为 NULL 或重复值),MySQL 可能选择不使用索引。
- 例如,
WHERE column IS NULL,如果大部分值为 NULL,索引可能失效。
-
全表扫描更快
- 当 MySQL 优化器认为全表扫描比使用索引更快时,索引将失效。
- 通常发生在数据量较小或索引选择性较低的情况下。
-
索引列参与计算
- 查询条件中索引列参与计算,索引将失效。
- 例如,
WHERE column + 1 = 2,索引将失效。
-
使用
ORDER BY和GROUP BY时索引失效- 如果
ORDER BY或GROUP BY的列与索引列不一致,索引可能失效。 - 例如,索引为
(A, B),但ORDER BY B, A,索引将失效。
- 如果