1. 索引失效的常见场景与底层原理
作为一名数据库管理员,我见过太多因为索引失效导致的性能问题。索引就像图书馆的目录系统,设计得当能快速定位数据,但使用不当反而会成为负担。以下是几种典型的索引失效场景及其背后的工作原理。
1.1 最左前缀法则的深度解析
联合索引的最左前缀法则,本质上与B+树的数据结构直接相关。以索引(a,b,c)为例,数据库实际存储的索引结构是这样的:
code复制a=1
b=10
c=100 → 数据指针
c=101 → 数据指针
b=11
c=110 → 数据指针
a=2
b=20
c=200 → 数据指针
当查询条件缺少a字段时,数据库引擎就像在图书馆里不知道书架编号,只能逐个书架查找。这就是为什么WHERE b=1 AND c=2无法有效使用索引的原因。
实战经验:在设计联合索引时,应该把区分度最高的字段放在最左边。可以通过
SELECT COUNT(DISTINCT column)/COUNT(*)计算字段区分度。
1.2 隐式类型转换的代价
当发生隐式类型转换时,数据库引擎必须对索引列的值逐行应用转换函数。以user_id INT字段为例:
sql复制-- 索引失效的写法
SELECT * FROM users WHERE user_id = '123';
-- 实际执行时相当于
SELECT * FROM users WHERE CAST(user_id AS CHAR) = '123';
这种转换导致数据库无法直接使用索引的有序性,必须扫描所有索引条目。在千万级数据表中,这种查询可能从毫秒级变为分钟级。
1.3 其他常见失效场景
除了上述两种情况,这些场景也会导致索引失效:
-
在索引列上使用函数:
sql复制-- 错误示例 SELECT * FROM logs WHERE DATE(create_time) = '2023-01-01'; -- 正确写法 SELECT * FROM logs WHERE create_time >= '2023-01-01' AND create_time < '2023-01-02'; -
**使
