-
查询条件未使用索引列
描述:查询条件没有涉及索引列时,MySQL 会直接执行全表扫描。
示例:
sqlSELECT * FROM users WHERE non_indexed_column = 'example';解决方法:在需要频繁查询的列上创建索引。
-
查询条件对索引列使用了函数或表达式
描述:对索引列进行函数或表达式操作会导致索引失效。
示例:
sqlSELECT * FROM users WHERE LEFT(name, 3) = 'Ali';解决方法:避免对索引列进行变换,改为:
SELECT * FROM users WHERE name LIKE 'Ali%'; -
数据类型不一致引发隐式类型转换
描述:当查询条件值的类型与索引列类型不一致时,MySQL 会进行隐式类型转换。
示例:
sqlSELECT * FROM users WHERE phone = 1234567890; -- phone 是 VARCHAR解决方法:确保类型一致:
SELECT * FROM users WHERE phone = '1234567890'; -
联合索引使用时的范围查询阻断
描述:在联合索引中,如果某列的范围查询中断了索引的有序性,后续列的索引无法生效。
示例:
sqlSELECT * FROM users WHERE name = 'Alice' AND age > 30 AND city = 'New York';解决方法:调整查询逻辑或单独为后续列创建索引。
-
使用 OR 条件
描述:如果 OR 条件中有字段未使用索引,会导致整体索引失效。
示例:
sqlSELECT * FROM users WHERE name = 'Alice' OR age = 30;解决方法:拆分查询,用 UNION 替代:
sqlSELECT * FROM users WHERE name = 'Alice' UNION SELECT * FROM users WHERE age = 30; -
前置通配符的模糊查询
描述:LIKE 查询中使用前置通配符 % 时,无法利用索引。
示例:
sqlSELECT * FROM users WHERE name LIKE '%Alice';解决方法:替换为后置通配符 LIKE 'Alice%';使用全文索引:
ALTER TABLE users ADD FULLTEXT(name);sqlSELECT * FROM users WHERE MATCH(name) AGAINST('Alice'); -
不等值查询
描述:不等值操作符(!=、<>)通常会导致索引失效。
示例:
sqlSELECT * FROM users WHERE age != 30;解决方法:改写为范围查询:
SELECT * FROM users WHERE age < 30 OR age > 30; -
IN 子句列表过长
描述:IN 子句中参数过多时,索引可能失效。
示例:
sqlSELECT * FROM users WHERE id IN (1, 2, ..., 10000);解决方法:分批查询或控制 IN 参数数量:
SELECT * FROM users WHERE id BETWEEN 1 AND 5000; -
NULL 查询
描述:某些情况下对 NULL 值的查询可能导致索引失效。
示例:
sqlSELECT * FROM users WHERE email IS NULL;解决方法:避免使用 NULL,改为特定占位值。
-
ORDER BY 和 GROUP BY 不符合索引顺序
描述:排序或分组字段与索引顺序不匹配时,索引无法生效。
示例:
sqlSELECT * FROM users ORDER BY age, name; -- 索引顺序为(name, age)解决方法:调整查询或索引顺序一致。
-
索引列未覆盖查询字段
描述:查询中包含未索引的字段,可能导致回表或索引失效。
示例:
sqlSELECT age FROM users WHERE name = 'Alice';解决方法:创建覆盖索引:
ALTER TABLE users ADD INDEX(name, age); -
表统计信息过期
描述:表的统计信息不准确时,MySQL 优化器可能错误选择全表扫描。
解决方法:定期更新统计信息:ANALYZE TABLE users;
-
数据分布不均
描述:某些列的数据分布高度不均匀,可能导致索引失效。
示例:
sqlSELECT * FROM users WHERE gender = 'M'; -- gender 列 90% 的值相同解决方法:优化查询字段或调整数据分布。
-
子查询未优化
描述:子查询结果集过大时,索引失效。
示例:
sqlSELECT * FROM users WHERE id IN (SELECT user_id FROM orders WHERE total > 100);解决方法:改为 JOIN 查询:
SELECT u.* FROM users u JOIN orders o ON u.id = o.user_id WHERE o.total > 100; -
锁机制干扰(间隙锁)
描述:间隙锁可能阻止索引的高效使用。
示例:
sqlSELECT * FROM users WHERE id BETWEEN 10 AND 20 FOR UPDATE;解决方法:降低事务隔离级别至 Read Committed。
-
索引被动态调整
描述:MySQL 优化器动态调整索引,可能选择非最佳索引或直接全表扫描。
解决方法:使用 FORCE INDEX 强制指定索引:
SELECT * FROM users FORCE INDEX (idx_name) WHERE name = 'Alice'; -
聚合函数未走索引
描述:使用聚合函数(如 COUNT、SUM)时,索引可能无法被利用。
示例:
sqlSELECT COUNT(*) FROM users WHERE age > 30;解决方法:利用覆盖索引:
ALTER TABLE users ADD INDEX(age); -
使用了非等值 JOIN
描述:非等值连接可能导致索引失效。
示例:
sqlSELECT * FROM users u JOIN orders o ON u.id > o.user_id;解决方法:优化连接条件,尽量使用等值连接。
-
小表全表扫描替代索引扫描
描述:对于非常小的表,MySQL 优化器可能选择全表扫描而非索引。
示例:
sqlSELECT * FROM small_table WHERE id = 1;解决方法:无需优化,小表全表扫描的代价通常可以忽略。
-
分区表查询不走全局索引
描述:分区表的查询条件未覆盖分区键时,全局索引可能无法生效。
示例:
sqlSELECT * FROM partitioned_users WHERE city = 'New York';解决方法:在分区键上创建局部索引。
面试——MySql索引什么场景下会失效
你知道烟火吗2024-12-06 17:15
相关推荐
他们叫我一代大侠10 分钟前
Leetcode :模拟足球赛小组各种比分的出线状况snakecy24 分钟前
信息系统项目管理师--论文casecsdn_aspnet42 分钟前
CentOS 7 上安装 MySQL 8.0uhakadotcom1 小时前
在使用cloudflare workers时,假如有几十个请求,如何去控制并发?AnRan08082 小时前
产业投资工作坊: 清洁能源赛道分析与投资实战一只小bit3 小时前
MySQL事务:如何保证ACID?MVCC到底如何工作?·云扬·3 小时前
使用pt-archiver实现MySQL数据归档与清理的完整实践weixin_46684 小时前
安装Zabbix7