面试——MySql索引什么场景下会失效

  1. 查询条件未使用索引列

    描述:查询条件没有涉及索引列时,MySQL 会直接执行全表扫描。

    示例:

    sql 复制代码
    SELECT * FROM users WHERE non_indexed_column = 'example';

    解决方法:在需要频繁查询的列上创建索引。

  2. 查询条件对索引列使用了函数或表达式

    描述:对索引列进行函数或表达式操作会导致索引失效。

    示例:

    sql 复制代码
    SELECT * FROM users WHERE LEFT(name, 3) = 'Ali';

    解决方法:避免对索引列进行变换,改为:SELECT * FROM users WHERE name LIKE 'Ali%';

  3. 数据类型不一致引发隐式类型转换

    描述:当查询条件值的类型与索引列类型不一致时,MySQL 会进行隐式类型转换。

    示例:

    sql 复制代码
    SELECT * FROM users WHERE phone = 1234567890; -- phone 是 VARCHAR

    解决方法:确保类型一致:SELECT * FROM users WHERE phone = '1234567890';

  4. 联合索引使用时的范围查询阻断

    描述:在联合索引中,如果某列的范围查询中断了索引的有序性,后续列的索引无法生效。

    示例:

    sql 复制代码
    SELECT * FROM users WHERE name = 'Alice' AND age > 30 AND city = 'New York';

    解决方法:调整查询逻辑或单独为后续列创建索引。

  5. 使用 OR 条件

    描述:如果 OR 条件中有字段未使用索引,会导致整体索引失效。

    示例:

    sql 复制代码
    SELECT * FROM users WHERE name = 'Alice' OR age = 30;

    解决方法:拆分查询,用 UNION 替代:

    sql 复制代码
    SELECT * FROM users WHERE name = 'Alice'
    UNION
    SELECT * FROM users WHERE age = 30;
  6. 前置通配符的模糊查询

    描述:LIKE 查询中使用前置通配符 % 时,无法利用索引。

    示例:

    sql 复制代码
    SELECT * FROM users WHERE name LIKE '%Alice';

    解决方法:替换为后置通配符 LIKE 'Alice%';使用全文索引:ALTER TABLE users ADD FULLTEXT(name);

    sql 复制代码
    SELECT * FROM users WHERE MATCH(name) AGAINST('Alice');
  7. 不等值查询

    描述:不等值操作符(!=、<>)通常会导致索引失效。

    示例:

    sql 复制代码
    SELECT * FROM users WHERE age != 30;

    解决方法:改写为范围查询:SELECT * FROM users WHERE age < 30 OR age > 30;

  8. IN 子句列表过长

    描述:IN 子句中参数过多时,索引可能失效。

    示例:

    sql 复制代码
    SELECT * FROM users WHERE id IN (1, 2, ..., 10000);

    解决方法:分批查询或控制 IN 参数数量:SELECT * FROM users WHERE id BETWEEN 1 AND 5000;

  9. NULL 查询

    描述:某些情况下对 NULL 值的查询可能导致索引失效。

    示例:

    sql 复制代码
    SELECT * FROM users WHERE email IS NULL;

    解决方法:避免使用 NULL,改为特定占位值。

  10. ORDER BY 和 GROUP BY 不符合索引顺序

    描述:排序或分组字段与索引顺序不匹配时,索引无法生效。

    示例:

    sql 复制代码
    SELECT * FROM users ORDER BY age, name; -- 索引顺序为(name, age)

    解决方法:调整查询或索引顺序一致。

  11. 索引列未覆盖查询字段

    描述:查询中包含未索引的字段,可能导致回表或索引失效。

    示例:

    sql 复制代码
    SELECT age FROM users WHERE name = 'Alice';

    解决方法:创建覆盖索引:ALTER TABLE users ADD INDEX(name, age);

  12. 表统计信息过期

    描述:表的统计信息不准确时,MySQL 优化器可能错误选择全表扫描。

    解决方法:定期更新统计信息:ANALYZE TABLE users;

  13. 数据分布不均

    描述:某些列的数据分布高度不均匀,可能导致索引失效。

    示例:

    sql 复制代码
    SELECT * FROM users WHERE gender = 'M'; -- gender 列 90% 的值相同

    解决方法:优化查询字段或调整数据分布。

  14. 子查询未优化

    描述:子查询结果集过大时,索引失效。

    示例:

    sql 复制代码
    SELECT * 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;

  15. 锁机制干扰(间隙锁)

    描述:间隙锁可能阻止索引的高效使用。

    示例:

    sql 复制代码
    SELECT * FROM users WHERE id BETWEEN 10 AND 20 FOR UPDATE;

    解决方法:降低事务隔离级别至 Read Committed。

  16. 索引被动态调整

    描述:MySQL 优化器动态调整索引,可能选择非最佳索引或直接全表扫描。

    解决方法:使用 FORCE INDEX 强制指定索引:SELECT * FROM users FORCE INDEX (idx_name) WHERE name = 'Alice';

  17. 聚合函数未走索引

    描述:使用聚合函数(如 COUNT、SUM)时,索引可能无法被利用。

    示例:

    sql 复制代码
    SELECT COUNT(*) FROM users WHERE age > 30;

    解决方法:利用覆盖索引:ALTER TABLE users ADD INDEX(age);

  18. 使用了非等值 JOIN

    描述:非等值连接可能导致索引失效。

    示例:

    sql 复制代码
    SELECT * FROM users u JOIN orders o ON u.id > o.user_id;

    解决方法:优化连接条件,尽量使用等值连接。

  19. 小表全表扫描替代索引扫描

    描述:对于非常小的表,MySQL 优化器可能选择全表扫描而非索引。

    示例:

    sql 复制代码
    SELECT * FROM small_table WHERE id = 1;

    解决方法:无需优化,小表全表扫描的代价通常可以忽略。

  20. 分区表查询不走全局索引

    描述:分区表的查询条件未覆盖分区键时,全局索引可能无法生效。

    示例:

    sql 复制代码
    SELECT * FROM partitioned_users WHERE city = 'New York';

    解决方法:在分区键上创建局部索引。

相关推荐
测试界萧萧3 小时前
15:00面试,15:08就出来了,问的问题有点变态。。。
自动化测试·软件测试·功能测试·程序人生·面试·职场和发展
先生先生3933 小时前
Java小公司面试
面试
小天努力学java3 小时前
【面试系列】深入浅出 Spring
java·spring·面试
dengjiayue4 小时前
MySQL 查询大偏移量(LIMIT)问题分析
数据库·mysql
言之。4 小时前
【MySQL】在MySQL中如何定位慢查询?
数据库·mysql
Suwg2094 小时前
【MySQL】踩坑笔记——保存带有换行符等特殊字符的数据,需要进行转义保存
数据库·笔记·mysql
PittDing4 小时前
【更新】Docker新手入门教程2:在Windows系统通过compose创建多个mysql镜像并配置应用
windows·mysql·docker
-$_$-4 小时前
【LeetCode 面试经典150题】详细题解之哈希表篇
leetcode·面试·散列表
m0_672449605 小时前
前后端分离(前端删除数据库数据)
java·数据库·mysql
正在绘制中5 小时前
Java重要面试名词整理(八):RabbitMQ
java·面试·java-rabbitmq