-
查询条件未使用索引列
描述:查询条件没有涉及索引列时,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
相关推荐
01_9 分钟前
力扣hot100——LRU缓存(面试高频考题)沐千熏34 分钟前
Liunx(CentOS-6-x86_64)系统安装MySql(5.6.50)小天努力学java1 小时前
【面试系列】Java开发--AI常见面试题StickToForever2 小时前
第4章 信息系统架构(三)SylviaW083 小时前
python-leetcode 35.二叉树的中序遍历篮l球场3 小时前
LeetCodehot 力扣热题100sunnyday04263 小时前
MyBatis XML映射文件中的批量插入和更新一个 00 后的码农3 小时前
25林业研究生复试面试问题汇总 林业专业知识问题很全! 林业复试全流程攻略 林业考研复试真题汇总浪九天3 小时前
Orcale、MySQL中参数类型的详解和运用场景(不带示例)程序员阿鹏3 小时前
jdbc批量插入数据到MySQL