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

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.xdnf.cn/news/872893.html

相关文章:

  • Qt 中实现文本截断(ellipsis)的功能。Qt 提供了此方法来处理过长的文本显示问题,例如在界面中限制文本长度并添加省略号(...)
  • Hugging Face 最新开源 SmolVLA 小模型入门教程(一)
  • 时序动作定位任务thumos14数据集标注文件处理
  • 【统计方法】蒙特卡洛
  • AT2401C中科微2.4g芯片PA
  • Starrocks中RoaringBitmap杂谈
  • 48V带极性反接保护-差共模浪涌防护方案
  • 5分钟了解JVM运行时数据区域
  • 【TCP/IP和OSI模型以及区别——理论汇总】
  • Vue2生命周期函数解析与应用
  • 项目练习:Vue2中el-button上的@click事件失效
  • 农业植保无人机核心技术从理论到实现
  • 无相关标签的精确零镜头密集检索
  • 60天python训练计划----day44
  • 理解网络协议
  • PX4 + D435i 进行gazebo仿真
  • Odoo 18 定期发送电子邮件报告(如KPI)配置指南
  • 力扣热题100之二叉树的直径
  • EMCC 13c 报错 “Metrics Global Cache Blocks Lost is at XXX“ 解决
  • TiDB单机生产环境下离线安装
  • 【Linux 】centos8搭建nextcloud全过程
  • 航芯MCU使用IAR+Jlink调试
  • C++算法训练营 Day8 字符串(1)
  • C++ 类一
  • 笔记 | docker构建失败
  • 乡村三维建模 | 江苏农田无人机建模案例
  • 深入解析FutureTask:原理与实战
  • 【RAG召回优化】rag召回阶段方法探讨
  • 学习STC51单片机27(芯片为STC89C52RCRC)
  • 34.1STM32下的can总线实现知识(区分linux)_csdn