索引分类
在 MySQL 中,索引是数据库优化查询性能的关键部分。不同的存储引擎(如 InnoDB 和 MyISAM)使用不同类型的索引结构,下面是 MySQL 中常见的几种索引结构:
1. B+ 树索引(B+ Tree Index)
- B+ 树索引是最常见的索引类型,主要用于 InnoDB 和 MyISAM 存储引擎。
- 采用的是 B+ 树,它是 B 树 的一种变种。所有数据存储在叶子节点,并且叶子节点之间通过指针相连,形成一个链表。
- 特点:
- 支持高效的等值查询和范围查询。
- 可以进行排序操作。
- 对于大数据量的查询效率非常高。
- 用途:用于 主键索引、普通索引(非唯一)、唯一索引、联合索引。
2. 哈希索引(Hash Index)
- 哈希索引通常用于 Memory 存储引擎,也可以在某些情况下用于 InnoDB(例如,在特定的存储引擎配置中)或其他存储引擎中。
- 基于 哈希表,使用哈希函数将键值映射到表的特定位置。
- 特点:
- 只适用于 等值查询,例如
=
和IN
查询。 - 不支持范围查询。
- 对于等值查询,查询速度非常快(O(1) 时间复杂度)。
- 只适用于 等值查询,例如
- 用途:在 Memory 存储引擎中用作默认的索引类型。
3. 全文索引(Fulltext Index)
- 全文索引用于文本数据的搜索,尤其适合处理 MyISAM 或 InnoDB 中的文本字段(如
TEXT
或VARCHAR
)。 - 特点:
- 可以通过 MATCH 和 AGAINST 操作符执行全文搜索。
- 支持对单词进行索引和查询,适用于自然语言的匹配。
- 用途:用于 文本搜索,如查找包含某个关键词的记录。
4. 空间索引(Spatial Index)
- 空间索引用于存储和查询 空间数据(如几何数据),例如点、线、面等。
- 常用于 MyISAM 存储引擎,它使用 R 树 或 Quad树 等数据结构来构建空间索引。
- 特点:
- 适用于 地理信息系统(GIS) 等应用中的空间数据查询。
- 支持 范围查询 和 邻近查询。
- 用途:用于地理位置、地图数据、GIS 查询等。
5. 倒排索引(Inverted Index)
- 倒排索引通常用于 全文索引,它将文档中出现的每个单词映射到文档ID,形成一个倒排的索引列表。
- 特点:
- 特别适合用于文本搜索,通过倒排索引可以快速找到包含特定单词的文档。
- 用途:主要用于 全文搜索,支持复杂的文本查询。
6. 聚簇索引(Clustered Index)
- 聚簇索引是 InnoDB 存储引擎中主键索引的一个特性,数据表的记录本身就按主键的顺序存储。
- 特点:
- 聚簇索引本质上是 主键索引,表中的数据按主键顺序存储,因此聚簇索引的数据文件就是索引文件。
- 一个表只能有一个聚簇索引,因为数据本身只能按一种顺序存储。
- 用途:用于 主键索引,所有基于主键的查询都会使用聚簇索引。
7. 非聚簇索引(Non-Clustered Index)
- 非聚簇索引是表的一种独立的索引结构,数据表的记录和索引的顺序不一致。InnoDB 和 MyISAM 都可以使用非聚簇索引。
- 特点:
- 非聚簇索引是独立于数据存储的,它存储的是数据行的指针(而不是数据本身)。
- 一个表可以有多个非聚簇索引。
- 用途:用于 非主键索引 或 唯一索引。
8. 组合索引(Composite Index)
- 组合索引是由多个列构成的索引。当查询涉及多个列时,组合索引能显著提高查询效率。
- 特点:
- 适用于多列查询,能够减少多个列的联合查询的开销。
- 组合索引是按照索引列的顺序构建的。
- 用途:用于多列查询、联合查询。
9. 唯一索引(Unique Index)
- 唯一索引是一种特殊的索引类型,要求索引列中的值唯一。
- 特点:
- 可以加速查询,但不能有重复的值。
- 与普通索引的区别在于它有额外的约束,确保数据的唯一性。
- 用途:用于确保数据列的唯一性(如用户 ID、电子邮件地址等)。
总结:
- B+ 树索引 是 MySQL 最常用的索引结构,特别适用于范围查询和排序操作。
- 哈希索引 主要用于 Memory 存储引擎,不适合范围查询,只能用于等值查询。
- 全文索引 适合处理文本内容,特别是用于实现快速的全文搜索。
- 空间索引 用于地理信息数据的处理。
- 聚簇索引 是数据本身按索引存储,主要用于 InnoDB 中的主键索引。
- 非聚簇索引 存储的是数据的指针,通常用于其他类型的索引。
每种索引类型都有其特定的应用场景和性能优势,根据数据特点和查询需求选择合适的索引结构可以显著提高数据库性能。
索引失效情况
在 MySQL 中,索引可以大大提高查询性能,但在某些情况下,索引可能会失效(即无法发挥预期的加速作用)。索引失效通常发生在查询优化器认为使用索引不会带来性能提升时,或者查询的条件和使用方式不适合索引。以下是一些常见的情况下索引会失效:
1. 使用 OR
时
- 在查询中使用
OR
条件时,如果其中某个条件不能使用索引,整个索引可能会失效。MySQL 可能会选择不使用索引,转而使用全表扫描。
示例:
SELECT * FROM employees WHERE name = 'Alice' OR age = 30;
如果 name
列上有索引,但 age
列没有索引,MySQL 可能会放弃使用索引而进行全表扫描。优化方法是确保每个条件都有索引,或者将查询重写为 UNION
语句。
2. 使用 NOT
、IS NULL
、IS NOT NULL
- 对于
NOT
、IS NULL
和IS NOT NULL
的查询条件,索引可能失效。
示例:
SELECT * FROM employees WHERE name IS NOT NULL;
或者:
SELECT * FROM employees WHERE age NOT IN (30, 40, 50);
在这些情况下,索引可能无法有效使用,尤其是当查询条件使用了反向操作或 null 检查时。
3. 对索引列进行函数操作
- 当在查询条件中对索引列使用函数(如
LOWER()
,UPPER()
,DATE()
,CONCAT()
等)时,索引将失效,因为这些函数的应用会导致无法直接匹配原始索引值。
示例:
SELECT * FROM employees WHERE LOWER(name) = 'alice';
在这个例子中,LOWER(name)
会导致索引失效。为了避免索引失效,可以避免使用函数,或者将数据存储为统一格式(例如,将所有名称存储为小写字母)。
4. 范围查询中的索引列后续字段没有用到
- 在使用范围查询(如
BETWEEN
,>
,<
,>=
,<=
,LIKE
等)时,如果索引列后有其他列没有使用,索引可能会失效。索引会按照列的顺序使用,一旦遇到范围查询,后续的列通常不会参与索引。
示例:
SELECT * FROM employees WHERE age > 30 AND name = 'Alice';
如果 age
列在索引的前面,而 name
列在后面,age > 30
会使用索引,但 name = 'Alice'
可能不会。解决方法是确保在适当的顺序使用索引,或者调整查询顺序。
5. 使用 LIKE
通配符匹配时,前缀是 %
- 当
LIKE
查询中使用了以%
开头的通配符时,索引将失效,因为这种查询无法通过索引加速。
示例:
SELECT * FROM employees WHERE name LIKE '%lice';
由于 %
通配符位于查询的开头,MySQL 无法使用索引来优化查询,必须进行全表扫描。优化的方法是避免使用前缀 %
,或者使用 全文索引。
6. 不符合索引的排序(ORDER BY
)
- 如果查询包含了
ORDER BY
子句,并且排序的列与索引不一致(例如,索引列的顺序和ORDER BY
的顺序不匹配),索引可能不会被使用,或者使用索引的效率较低。
示例:
SELECT * FROM employees ORDER BY age DESC, name ASC;
如果索引是按 age ASC
或 name ASC
排序的,那么它就不适用于此查询。如果查询的排序顺序和索引的顺序不一致,可能需要进行全表扫描。
7. DISTINCT
或 GROUP BY
语句
- 当查询使用
DISTINCT
或GROUP BY
时,可能会导致索引失效,特别是在没有合适的索引支持时。MySQL 可能会选择进行全表扫描以满足查询需求。
示例:
SELECT DISTINCT name FROM employees WHERE age > 30;
如果 name
和 age
没有合适的复合索引,MySQL 可能无法有效使用索引,而进行全表扫描。
8. 使用 IN
查询时元素个数较多
- 当使用
IN
子句时,索引可能会失效,尤其是在IN
子句中列出了很多值。如果查询涉及多个值,MySQL 会计算是否能够通过索引使用最优的执行计划。
示例:
SELECT * FROM employees WHERE age IN (30, 40, 50, 60, 70, 80, 90, 100);
在某些情况下,如果 IN
子句中包含大量值,MySQL 可能会放弃使用索引,进行全表扫描。
9. JOIN 查询中的不当索引使用
- 在多表连接查询中,如果连接条件没有使用索引,或者连接字段上没有合适的索引,MySQL 可能会选择全表扫描。
示例:
SELECT * FROM employees e JOIN departments d ON e.department_id = d.id WHERE d.name = 'HR';
如果 employees.department_id
或 departments.id
没有索引,MySQL 可能会进行全表扫描。
10. 使用不等于(<>
或 !=
)操作符
- 使用
<>
或!=
时,索引通常无法有效使用,因为 MySQL 无法快速定位到与某个值不相等的所有记录。
示例:
SELECT * FROM employees WHERE age <> 30;
在这种情况下,MySQL 可能会选择全表扫描,而不是使用索引。
11. 数据量较少时索引可能不被使用
- 对于非常小的数据集,MySQL 可能会判断全表扫描比使用索引更高效。即使有索引,MySQL 可能选择全表扫描,因为全表扫描的开销可能更低。
结论
要确保 MySQL 中的索引尽可能有效,建议遵循以下最佳实践:
- 避免在索引列上使用函数、
OR
、NOT
、IS NULL
等操作。 - 避免在
LIKE
查询中使用前缀%
。 - 确保查询条件的顺序和索引的顺序一致。
- 在多表查询中确保连接字段上有索引。
通过合理设计索引和查询,可以有效提升 MySQL 的查询性能。
创建索引需要注意的点
在 MySQL 中创建索引时,正确的设计和使用索引非常关键,因为不当的索引设计可能会影响查询性能,甚至导致性能下降。创建索引时需要注意以下几点:
1. 选择合适的列作为索引
- 查询频繁的列:通常索引应当应用在查询中频繁使用的列,特别是作为查询条件(
WHERE
子句)的一部分的列。- 例如:
SELECT * FROM employees WHERE name = 'Alice';
如果name
列在表中频繁用于查询条件,那么name
列是创建索引的候选。
- 例如:
- 作为连接条件的列:在多表连接查询(
JOIN
)中,连接条件中经常涉及的列也是创建索引的好候选。- 例如:
SELECT * FROM employees e JOIN departments d ON e.department_id = d.id;
,e.department_id
和d.id
可以考虑创建索引。
- 例如:
- 排序和分组的列:如果查询中常常使用
ORDER BY
或GROUP BY
对某个列排序或分组,该列也应该加上索引。
避免对低基数列(如布尔类型列、性别等)创建索引,因为这些列的索引并不会提高查询性能,反而可能会增加存储和维护成本。
2. 索引的选择:单列索引与复合索引
- 单列索引:对于经常单独用于查询的列(例如,某一列用于独立的
WHERE
子句),可以使用单列索引。 - 复合索引:对于涉及多个列的查询,可以考虑创建复合索引(即多列索引),尤其是当查询经常同时涉及多个列时。
- 复合索引的顺序非常重要,应该根据查询条件中列的顺序来确定复合索引的列顺序(遵循最左前缀原则)。
例如,如果你的查询经常是 WHERE age > 30 AND name = 'Alice'
,那么可以考虑创建 (age, name)
的复合索引。若查询条件是 WHERE name = 'Alice'
,那么单列索引 name
可能更合适。
3. 避免过多的索引
- 虽然索引能提高查询性能,但过多的索引会带来负面影响:
- 插入、更新和删除操作的性能下降:每次插入、更新或删除数据时,索引都需要同步更新,因此过多的索引会导致这些操作的性能显著下降。
- 增加存储空间:每个索引都需要占用额外的存储空间。
- 优化建议:只为查询频繁的列创建索引,避免为不常用的列或每个查询条件都创建单独的索引。
4. 索引类型的选择
- B+ 树索引:MySQL 默认使用 B+ 树索引(例如,InnoDB 和 MyISAM 存储引擎),它适用于等值查询、范围查询、排序和分组操作。
- 哈希索引:适用于内存引擎(如 MEMORY 存储引擎),哈希索引速度非常快,但只支持等值查询(
=
和IN
)。 - 全文索引(Fulltext Index):用于文本数据的全文搜索(
MATCH
和AGAINST
),适用于TEXT
或VARCHAR
类型的数据。 - 空间索引(Spatial Index):用于地理空间数据,适用于 MyISAM 存储引擎,支持空间数据的查询,如
ST_Distance
、ST_Intersects
等。
5. 选择合适的数据类型
- 使用合适的数据类型(例如,使用 整数 而不是 字符 类型),能让索引更加高效。
- 较小的数据类型:如果索引列的数据类型较大(例如
BIGINT
或TEXT
类型),索引的存储和查询性能都会受到影响。因此,选择合适的数据类型会提高查询性能。- 例如,如果你只需要存储 0 到 255 之间的数字,可以使用
TINYINT
而不是INT
,节省空间和提升性能。
- 例如,如果你只需要存储 0 到 255 之间的数字,可以使用
6. 考虑索引的唯一性
- 唯一索引(Unique Index):确保列值唯一,可以用来防止重复数据。对于主键(
PRIMARY KEY
)和要求唯一的列,MySQL 会自动创建唯一索引。 - 非唯一索引(Non-Unique Index):如果列允许重复值且查询中频繁使用该列,可以创建非唯一索引。注意,非唯一索引仍然能提高查询性能。
7. 避免不适合使用索引的查询
- 避免对索引列使用函数操作:对索引列使用
LOWER()
、DATE()
等函数时,索引会失效,导致查询性能下降。 - 避免对索引列使用
OR
和NOT
操作符:OR
和NOT
操作符可能会导致无法有效使用索引,尤其是当OR
右侧的条件没有索引时。 - 避免使用
LIKE '%pattern'
:LIKE
查询前缀为%
时,MySQL 无法使用索引进行优化。
8. 保持索引的最新状态
- 定期优化索引:MySQL 支持对索引进行优化(例如,使用
OPTIMIZE TABLE
)。随着数据的插入、更新和删除,索引可能会变得不够高效,定期维护索引可以保证查询性能。 - 监控索引的使用情况:使用工具如
EXPLAIN
来查看查询计划,确认索引是否被正确使用,避免冗余索引。
9. 使用合适的存储引擎
- InnoDB 存储引擎是 MySQL 默认的存储引擎,支持 事务 和 行级锁定,并且默认使用 B+ 树索引。
- MyISAM 存储引擎适用于读取较多、写入较少的场景,支持全文索引,但不支持事务。
10. 避免过多的复合索引
- 在某些情况下,为多个列创建复合索引可能导致查询性能下降,因为每个查询都需要考虑多个列。使用复合索引时要确保它能够覆盖你的查询。
11. 避免使用过多的索引字段
- 创建索引时,应避免将多个字段一起创建过于复杂的复合索引,避免造成不必要的开销。特别是在列数过多时,索引本身可能会变得非常庞大,影响性能。
总结
在 MySQL 中创建索引时,需要根据以下原则进行优化:
- 只为查询频繁的列创建索引,避免过多的索引。
- 选择合适的索引类型,如 B+ 树索引、全文索引、哈希索引等。
- 考虑索引的顺序,特别是复合索引。
- 避免索引失效的查询操作,如在索引列上使用函数、
OR
和NOT
操作符、LIKE '%pattern'
等。 - 定期优化和监控索引的使用情况,确保索引能够提升查询性能。
通过合理设计和使用索引,可以显著提高 MySQL 的查询性能,但过多或不合适的索引则可能导致性能下降。
最左匹配原则
在 MySQL 中,最左匹配原则(Leftmost Prefix Rule)是指在复合索引(由多个列组成的索引)中,索引会尽可能从左到右使用列,并且只要查询条件匹配索引的前缀部分,MySQL 就会利用这个索引。
具体来说,最左匹配原则意味着复合索引中的列顺序非常重要。索引只能从左到右匹配,如果查询中没有使用索引的最左边列,那么索引就无法被利用。
1. 最左匹配原则的工作原理
假设我们有一个包含多个列的复合索引,例如:
CREATE INDEX idx_name_age_gender ON employees (name, age, gender);
这个索引是由 name
, age
, 和 gender
组成的复合索引。根据最左匹配原则,MySQL 会根据查询中的条件,尽量从左到右使用索引列。具体来说:
- 如果查询中涉及
name
列,MySQL 可以使用该索引。 - 如果查询中涉及
name
和age
两列,MySQL 可以使用该索引。 - 如果查询中涉及
name
、age
和gender
三列,MySQL 仍然可以使用该索引。 - 如果查询中只涉及
age
和gender
,但是没有name
列,则无法使用该索引(因为name
是最左边的列,age
和gender
不是索引的最左前缀)。 - 如果查询只涉及
gender
列,MySQL 也无法使用该索引。
2. 最左匹配原则的总结
- 最左匹配原则要求查询必须从复合索引的最左侧列开始,并且按顺序匹配。如果查询中没有使用索引的最左边列,索引就无法被使用。
- 如果查询条件中使用了索引的前缀列(即最左边的列及其右侧列),则索引可以被利用。
- 如果查询条件中只涉及复合索引中的中间列或末尾列,而没有涉及最左边的列,则索引无法被利用。
3. 最左匹配原则的优化建议
- 设计复合索引时要考虑查询模式:你应该根据查询中最常用的列顺序来设计复合索引,确保最常用的列放在索引的最前面。
- 避免无效的索引顺序:如果你有复合索引
(name, age, gender)
,但查询中频繁只使用age
或gender
列,而不使用name
列,那么这个索引可能不适合此类查询。此时,你可能需要创建单列索引或者考虑重新设计索引。
4. 复合索引与 ORDER BY
和 GROUP BY
的关系
复合索引不仅能提高查询效率,还可以帮助优化 ORDER BY
和 GROUP BY
操作。只要查询中的排序列与索引的顺序一致,MySQL 就能利用该索引来加速排序:
- 如果查询中的
ORDER BY
列和复合索引的顺序一致,MySQL 可以利用该索引返回已经排序的数据,从而避免额外的排序开销。
如果SELECT * FROM employees ORDER BY name, age;
name
和age
是复合索引的前两列,MySQL 就可以利用这个索引直接返回按这两个列排序的结果。
5. 优化复合索引的设计
- 考虑常用查询的顺序:将查询最常使用的列放在索引的最左边,以便能够利用最左匹配原则。
- 避免创建过多的复合索引:尽量避免为每个查询条件都创建一个复合索引。要根据查询模式来合理设计复合索引,减少不必要的索引。
- 避免不必要的排序:如果查询中使用了
ORDER BY
,且排序列正好是复合索引的前缀列,那么MySQL可以直接使用索引来排序,避免额外的排序操作。
通过合理使用最左匹配原则,可以显著提高查询性能,确保复合索引的高效利用。
阻断最左匹配原则
在 MySQL 中,虽然最左匹配原则(Leftmost Prefix Rule)对于复合索引的高效利用至关重要,但在一些特定情况下,这个原则会被阻断,导致索引无法发挥预期作用。以下是几种常见的情况,可能会阻断最左匹配原则的正常使用:
1. 查询条件不包含索引的最左边列
最左匹配原则的核心是 查询条件必须包括复合索引的最左边列,否则索引无法被有效利用。如果查询条件中没有包含复合索引的最左边列,则该复合索引无法使用。
示例:
假设有以下复合索引:
CREATE INDEX idx_name_age_gender ON employees (name, age, gender);
查询1:使用了
name
和age
:SELECT * FROM employees WHERE name = 'Alice' AND age = 30;
此查询可以使用索引,因为查询条件包含了索引的前两个列(
name
和age
)。查询2:只使用
age
:SELECT * FROM employees WHERE age = 30;
此查询不能使用索引,因为查询没有涉及索引的最左边列
name
。查询3:只使用
gender
:SELECT * FROM employees WHERE gender = 'M';
此查询也不能使用索引,因为查询条件没有涉及最左侧的列
name
,并且gender
在复合索引中是最后一列。
2. 查询条件中的列顺序与索引列顺序不匹配
在复合索引中,列的顺序非常重要。最左匹配原则要求查询条件中的列顺序和复合索引中的列顺序保持一致。如果查询条件中的列顺序与复合索引中列的顺序不一致,MySQL 就无法利用该索引。
示例:
假设有以下复合索引:
CREATE INDEX idx_name_age_gender ON employees (name, age, gender);
查询1:顺序与索引匹配:
SELECT * FROM employees WHERE name = 'Alice' AND age = 30;
此查询可以使用索引,因为查询条件的列顺序与索引列顺序完全一致。
查询2:顺序与索引不匹配:
SELECT * FROM employees WHERE age = 30 AND name = 'Alice';
此查询不能使用索引,因为查询条件的列顺序与索引的顺序不一致(
age
在name
之前,而索引的顺序是name, age
)。虽然列都被查询了,但由于顺序不同,MySQL 无法使用该索引。
3. 对索引列使用函数或表达式
当查询中对索引列使用了 函数、表达式 或 类型转换 时,MySQL 将无法利用索引进行优化,因为 MySQL 无法直接从索引中提取函数或表达式的值来进行高效匹配。
示例:
假设你有以下复合索引:
CREATE INDEX idx_name_age_gender ON employees (name, age, gender);
查询1:没有使用函数,符合最左匹配原则:
SELECT * FROM employees WHERE name = 'Alice' AND age = 30;
此查询可以使用索引。
查询2:对
name
列使用了函数(例如LOWER()
):SELECT * FROM employees WHERE LOWER(name) = 'alice' AND age = 30;
此查询不能使用索引,因为
LOWER(name)
对name
列使用了函数,MySQL 无法直接在索引中查找经过函数处理的值。查询3:对
age
列进行范围查询(例如BETWEEN
或<
):SELECT * FROM employees WHERE name = 'Alice' AND age > 30;
此查询依然可以使用索引,因为
name
列是最左边的列,并且对age
的范围查询不会阻止最左匹配原则的使用。
4. 查询条件中包含 OR
操作
使用 OR
操作符时,特别是当 OR
连接的不同条件涉及的列与复合索引的最左前缀不一致时,索引的使用可能会受到阻碍。MySQL 可能无法有效使用复合索引,尤其是在 OR
子句中存在不一致的列顺序时。
示例:
假设你有以下复合索引:
CREATE INDEX idx_name_age_gender ON employees (name, age, gender);
查询1:
OR
连接条件但列顺序一致:SELECT * FROM employees WHERE name = 'Alice' OR age = 30;
此查询可能无法完全利用索引,因为
OR
子句可能使 MySQL 使用两个独立的索引,而不是一个复合索引。查询2:
OR
子句中没有涉及最左侧的列:SELECT * FROM employees WHERE age = 30 OR gender = 'M';
此查询无法使用索引,因为查询条件中没有涉及复合索引的最左边列
name
,这导致最左匹配原则被阻断。
5. 查询条件中使用 NOT
操作符
当查询条件中使用 NOT
操作符时,通常会导致索引失效。NOT
操作符会使得 MySQL 无法通过索引进行高效的查询,因为索引通常只能有效地执行 等值 或 范围查询。
示例:
假设你有以下复合索引:
CREATE INDEX idx_name_age_gender ON employees (name, age, gender);
查询1:使用
NOT
操作符:SELECT * FROM employees WHERE NOT name = 'Alice';
此查询不能使用索引,因为
NOT
操作符导致 MySQL 无法使用索引进行快速查找。
6. LIKE
查询中使用 %
开头的模式
如果查询中使用 LIKE
并且模式以 %
开头(例如 %pattern
),索引将无法用于优化查询,因为 MySQL 无法使用索引来直接匹配以 %
开头的模式。
示例:
假设你有以下复合索引:
CREATE INDEX idx_name_age_gender ON employees (name, age, gender);
查询1:
LIKE
查询,模式不以%
开头:SELECT * FROM employees WHERE name LIKE 'Alice%';
此查询可以使用索引,因为
LIKE
查询是前缀匹配,可以利用索引。查询2:
LIKE
查询,模式以%
开头:SELECT * FROM employees WHERE name LIKE '%Alice';
此查询无法使用索引,因为
%
开头的模式会导致全表扫描,而索引无法优化这种查询。
总结
最左匹配原则可能会被以下几种情况阻断:
- 查询条件不包含索引的最左边列。
- 查询条件的列顺序与索引列顺序不匹配。
- 对索引列使用函数或表达式。
- 使用
OR
操作符且涉及的列与最左前缀不匹配。 - 使用
NOT
操作符。 LIKE
查询模式以%
开头。
理解这些情况有助于优化索引的使用,确保查询能够最大化地利用索引,提高性能。