SQL查询全表扫描主因是查询条件未有效触发索引使用。1.对索引列用函数或运算(如YEAR(create_time)=2025);2.LIKE以%开头(如name LIKE '%明');3.隐式类型转换(如VARCHAR字段传数字);4.联合索引未遵循最左前缀原则(如索引(a,b,c)只查b,c)。
SQL查询出现全表扫描,通常是因为数据库优化器没走索引,转
而逐行读取整张表——性能会随数据量增长急剧下降。核心问题不在于“有没有建索引”,而在于“查询条件能否有效触发索引的使用”。下面从常见场景出发,说清楚索引为啥失效、怎么避免。
数据库无法直接用索引定位值,必须先计算每行结果再比对,索引自然被跳过。
WHERE YEAR(create_time) = 2025 或 WHERE price * 1.1 > 100
WHERE create_time >= '2025-01-01' AND create_time ;价格比较改写为 WHERE price > 100 / 1.1
B+树索引按字典序存储,前缀匹配可快速定位,但%abc这种没有固定前缀,只能全扫。
WHERE name LIKE '%明' 或 WHERE name LIKE '%李%'
WHERE name LIKE '李%';若必须前后模糊,考虑全文索引(FULLTEXT)或ES等外部检索方案字段是字符串类型,但查询时传了数字;或字段是INT,却用字符串比较——MySQL会自动转换,但索引列被“加工”了,无法命中。
user_id 是 VARCHAR,却写 WHERE user_id = 123(数字);或 status 是 TINYINT,却写 WHERE status = '1'
EXPLAIN 查看 type 是否为 ALL,并检查 Extra 列是否含 Using where; Using index
联合索引 (a, b, c) 实际上只对 a、(a,b)、(a,b,c) 三种组合高效;跳过左边列(比如只查 b 或 b,c),索引就用不上。
WHERE b = 2 AND c = 3(缺少 a);WHERE a = 1 AND c = 3(跳过 b)(a,c) 单独建;用 EXPLAIN 看 key_len 值,判断实际用了索引的几列索引不是建了就生效,关键看查询写法是否与索引结构“对得上”。多用 EXPLAIN 验证执行计划,比死记规则更可靠。不复杂但容易忽略。