面试——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';

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

相关推荐
01_9 分钟前
力扣hot100——LRU缓存(面试高频考题)
leetcode·缓存·面试·lru
沐千熏34 分钟前
Liunx(CentOS-6-x86_64)系统安装MySql(5.6.50)
linux·mysql·centos
小天努力学java1 小时前
【面试系列】Java开发--AI常见面试题
java·人工智能·面试
StickToForever2 小时前
第4章 信息系统架构(三)
经验分享·笔记·学习·职场和发展
SylviaW083 小时前
python-leetcode 35.二叉树的中序遍历
算法·leetcode·职场和发展
篮l球场3 小时前
LeetCodehot 力扣热题100
算法·leetcode·职场和发展
sunnyday04263 小时前
MyBatis XML映射文件中的批量插入和更新
xml·java·mysql·mybatis
一个 00 后的码农3 小时前
25林业研究生复试面试问题汇总 林业专业知识问题很全! 林业复试全流程攻略 林业考研复试真题汇总
考研·面试·面试问题·考研复试·考研调剂·面试真题·林业考研
浪九天3 小时前
Orcale、MySQL中参数类型的详解和运用场景(不带示例)
数据库·mysql·oracle
程序员阿鹏3 小时前
jdbc批量插入数据到MySQL
java·开发语言·数据库·mysql·intellij-idea