当前位置: 首页 > article >正文

Mysql避免索引失效

1. 在索引列上使用函数或表达式

问题描述
SELECT * FROM users WHERE YEAR(create_time) = 2023;

如果create_time列上有索引,上述查询会导致索引失效,因为MySQL无法直接利用索引的B+树结构。

解决方法

将函数应用于条件值,而不是列:

SELECT * FROM users WHERE create_time >= '2023-01-01' AND create_time < '2024-01-01';

2. 使用类型隐式转换

问题描述
SELECT * FROM users WHERE phone = 13800138000;

如果phone列是VARCHAR类型,而条件值是整数,MySQL会进行隐式类型转换,导致索引失效。

解决方法

确保条件值与索引列类型一致:

SELECT * FROM users WHERE phone = '13800138000';

3. 使用不等于或不包含操作符

问题描述
SELECT * FROM users WHERE name != 'John';

使用!=<>NOT INNOT LIKE等否定条件时,通常会导致索引失效。

解决方法

尽量使用肯定条件替代否定条件。如果必须使用否定条件,可以考虑将查询拆分为多个子查询。

4. 使用OR操作符连接不同索引列

问题描述
SELECT * FROM users WHERE name = 'John' OR email = 'john@example.com';

如果nameemail列上有不同的索引,上述查询可能导致索引失效。

解决方法

使用UNION替代OR

SELECT * FROM users WHERE name = 'John'
UNION
SELECT * FROM users WHERE email = 'john@example.com';

或者创建复合索引(如果适用)。

5. 使用LIKE操作符且以通配符开头

问题描述
SELECT * FROM products WHERE product_name LIKE '%phone%';

以通配符%开头的LIKE查询会导致索引失效。

解决方法
  • 尽量使用后缀通配符:

    SELECT * FROM products WHERE product_name LIKE 'phone%';
  • 如果必须使用前缀通配符,可以考虑使用全文索引。

6. 对索引列进行运算

问题描述
SELECT * FROM products WHERE price + 100 > 500;

对索引列进行运算会导致索引失效。

解决方法

将运算应用于条件值,而不是列:

SELECT * FROM products WHERE price > 400;

7. 查询条件中的字段顺序与复合索引顺序不一致

问题描述
SELECT * FROM users WHERE age = 25 AND city = 'New York' AND name = 'John';

如果复合索引是(name, age, city),上述查询可能无法充分利用索引。

解决方法

保持查询条件顺序与索引列顺序一致:

SELECT * FROM users WHERE name = 'John' AND age = 25 AND city = 'New York';

8. 使用不等值范围查询

问题描述
SELECT * FROM employees WHERE age > 30 AND salary > 50000;

如果复合索引是(age, salary)salary部分无法使用索引。

解决方法

调整索引顺序,将范围查询的列放在最后:

CREATE INDEX idx_salary_age ON employees(salary, age);

9. ORDER BYGROUP BY子句使用不当

问题描述
SELECT * FROM orders ORDER BY order_date DESC;

如果order_date列上有索引,但查询条件中没有使用该列,可能导致额外的排序操作。

解决方法

确保ORDER BYGROUP BY子句中的字段与WHERE条件中使用的索引列一致,或者创建覆盖索引:

CREATE INDEX idx_order_date_status ON orders(order_date, order_status);

10. 查询的数据占表中数据的比例较大

问题描述
SELECT * FROM orders WHERE order_status = 'shipped';

如果order_status字段的选择性很低(例如只有两个值),MySQL优化器可能会选择全表扫描。

解决方法
  • 增加更多的过滤条件,减小结果集。

  • 使用覆盖索引避免回表查询。

11. 使用IS NULLIS NOT NULL

问题描述
SELECT * FROM users WHERE phone IS NULL;

如果phone列上有索引,IS NULLIS NOT NULL查询可能会导致索引失效。

解决方法

确保索引列允许NULL值,并且优化器能够正确利用索引。如果NULL值较多,可以考虑使用额外的字段或标志位。

12. 使用IN操作符

问题描述
SELECT * FROM users WHERE id IN (1, 2, 3);

如果IN操作符中的值较多,可能导致索引失效。

解决方法
  • 如果IN操作符中的值较少,可以使用UNION替代:

    SELECT * FROM users WHERE id = 1
    UNION
    SELECT * FROM users WHERE id = 2
    UNION
    SELECT * FROM users WHERE id = 3;
  • 如果IN操作符中的值较多,可以考虑将这些值存储在临时表中,然后通过JOIN操作查询。

13. 使用DISTINCT

问题描述
SELECT DISTINCT name FROM users WHERE age = 25;

如果name列上没有索引,DISTINCT操作可能导致性能问题。

解决方法

name列创建索引,或者使用GROUP BY替代DISTINCT

SELECT name FROM users WHERE age = 25 GROUP BY name;

14. 使用LIMIT

问题描述
SELECT * FROM orders ORDER BY order_date DESC LIMIT 10;

如果order_date列上有索引,但查询条件中没有使用该列,可能导致额外的排序操作。

解决方法

确保ORDER BY子句中的字段与WHERE条件中使用的索引列一致,或者创建覆盖索引:

CREATE INDEX idx_order_date_status ON orders(order_date, order_status);

总结

避免索引失效的关键在于:

  1. 遵循最左匹配原则。

  2. 避免在索引列上使用函数或表达式。

  3. 确保查询条件、排序和分组字段与索引列一致。

  4. 使用覆盖索引避免回表查询。

  5. 避免使用否定条件、OR操作符和前缀通配符。

  6. 定期分析和优化索引。

通过这些方法,可以有效避免索引失效,提升MySQL查询性能。

http://www.lryc.cn/news/2401227.html

相关文章:

  • python爬虫:Ruia的详细使用(一个基于asyncio和aiohttp的异步爬虫框架)
  • C++中单例模式详解
  • 舆情监控系统爬虫技术解析
  • Windows上用FFmpeg采集摄像头推流 → MediaMTX服务器转发流 → WSL2上拉流播放
  • cpp多线程学习
  • Vue3中Ant-design-vue的使用-附完整代码
  • k8s热更新-subPath 不支持热更新
  • Redis Sorted Set 深度解析:从原理到实战应用
  • docker中组合这几个命令来排查 import 模块失败 的问题
  • 若依框架修改模板,添加通过excel导入数据功能
  • web全栈开发学习-01html基础
  • 基于Socketserver+ThreadPoolExecutor+Thread构造的TCP网络实时通信程序
  • [Java 基础]枚举
  • 多线程环境中,如果多个线程同时尝试向同一个TCP客户端发送数据,添加同步机制
  • 【含文档+PPT+源码】基于微信小程序的旅游论坛系统的设计与实现
  • 贝叶斯优化+LSTM+时序预测=Nature子刊!
  • NodeJS全栈WEB3面试题——P3Web3.js / Ethers.js 使用
  • Quick UI 组件加载到 Axure
  • Vue3(ref与reactive)
  • Starrocks中RoaringBitmap杂谈
  • 通过ca证书的方式设置允许远程访问Docker服务
  • 涂胶协作机器人解决方案 | Kinova Link 6 Cobot在涂胶工业的方案应用与价值
  • 理解继承与组合的本质:Qt 项目中的设计选择指南
  • 新手小白使用VMware创建虚拟机安装Linux
  • 使用 PHP 和 Guzzle 对接印度股票数据源API
  • EscapeX:去中心化游戏,开启极限娱乐新体验
  • 使用PyQt5的图形用户界面(GUI)开发教程
  • STM32实战:智能环境监测站设计方案
  • 猎板硬金镀层厚度:新能源汽车高压系统的可靠性基石
  • KEYSIGHT是德科技 E5063A 18G ENA系列网络分析仪