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

Mysql索引失效的情况

MySQL 索引失效是影响查询性能的常见问题,指优化器本可使用索引却选择全表扫描的情况。以下是索引失效的常见场景及底层原因详解:

一、索引字段参与运算或函数操作

原理:索引存储的是字段原始值,若对字段进行运算或函数处理,优化器无法直接匹配索引值,只能全表扫描后再计算。

示例:
-- 1. 字段参与运算
SELECT * FROM users WHERE age + 1 = 30; -- 失效(age参与运算)
-- 正确写法:SELECT * FROM users WHERE age = 29;-- 2. 字段使用函数
SELECT * FROM users WHERE SUBSTR(name, 1, 1) = '张'; -- 失效(name被函数处理)
-- 优化方案:使用前缀索引(CREATE INDEX idx_name ON users(name(1));)-- 3. 日期函数滥用
SELECT * FROM orders WHERE DATE(create_time) = '2023-10-01'; -- 失效
-- 正确写法:SELECT * FROM orders WHERE create_time BETWEEN '2023-10-01 00:00:00' AND '2023-10-01 23:59:59';

二、模糊查询前缀含 %

原理:B+ 树索引是有序的,LIKE '%xxx' 或 LIKE '%xxx%' 无法通过索引有序性定位,只能全表扫描;而 LIKE 'xxx%' 可利用前缀匹配走索引。

示例:
-- 失效场景
SELECT * FROM users WHERE name LIKE '%三'; -- 前缀含%
SELECT * FROM users WHERE name LIKE '%三%'; -- 前后都含%-- 有效场景
SELECT * FROM users WHERE name LIKE '张%'; -- 仅后缀含%,可走索引

三、隐式类型转换

原理:字段类型与查询值类型不匹配时,MySQL 会自动转换类型(如字符串转数字),相当于对字段进行函数操作,导致索引失效。

示例:
-- 表结构:phone 是 VARCHAR 类型,且有索引
SELECT * FROM users WHERE phone = 13800138000; -- 失效(数字转字符串,相当于函数操作)
-- 正确写法:SELECT * FROM users WHERE phone = '13800138000'; -- 类型一致

四、使用 OR 连接非索引字段

原理OR 两侧若有一个字段无索引,优化器会认为全表扫描比部分走索引更高效(需合并两次结果),导致索引失效。

示例:
-- id 有索引,name 无索引
SELECT * FROM users WHERE id = 10 OR name = '张三'; -- 失效(name无索引)
-- 优化方案:
-- 1. 给 name 加索引;
-- 2. 拆分为两个查询:SELECT * FROM users WHERE id = 10 UNION SELECT * FROM users WHERE name = '张三';

五、联合索引违反 “最左前缀原则”

原理:联合索引 (a, b, c) 的生效顺序为 a → a+b → a+b+c,缺少最左字段 a 时,索引整体失效。

示例:
-- 联合索引:(user_id, status, create_time)
SELECT * FROM orders WHERE status = 1; -- 失效(缺少最左 user_id)
SELECT * FROM orders WHERE status = 1 AND create_time > '2023-01-01'; -- 失效
SELECT * FROM orders WHERE user_id = 100 AND create_time > '2023-01-01'; -- 部分生效(仅 user_id 走索引,create_time 不生效)
SELECT * FROM orders WHERE user_id = 100 AND status = 1; -- 完全生效

六、查询结果占表数据比例过大

原理:若索引查询结果超过表数据的 30%(经验值),MySQL 认为全表扫描比逐行查索引更高效(索引需多次 I/O,扫描一次完成)。

示例:
-- 表中有 100 万行,status=0 的数据有 50 万行(占 50%)
SELECT * FROM orders WHERE status = 0; -- 即使 status 有索引,也可能全表扫描

七、NOT IN!=<> 等操作符

原理:这些操作符会导致优化器认为匹配结果分散,索引定位效率低,倾向于全表扫描(视数据分布而定,并非绝对失效)。

示例:
SELECT * FROM users WHERE age != 30; -- 可能失效
SELECT * FROM users WHERE age NOT IN (20, 30); -- 可能失效

八、IS NOT NULL 操作(部分场景)

原理NULL 在索引中特殊存储,IS NOT NULL 需扫描大部分索引节点,效率接近全表扫描(而 IS NULL 可高效走索引)。

示例:
SELECT * FROM users WHERE email IS NOT NULL; -- 可能失效(若非NULL值占比高)
SELECT * FROM users WHERE email IS NULL; -- 有效(NULL值少,索引定位快)

九、优化器误判(统计信息过时)

原理:MySQL 依赖表统计信息(如数据量、字段分布)选择索引,若统计信息过时(如刚大批量插入数据),可能误判索引效率导致失效。

解决方法:
-- 手动更新统计信息
ANALYZE TABLE 表名;

如何检测索引是否失效?

使用 EXPLAIN 命令分析执行计划,若 type 为 ALL 且 key 为 NULL,说明索引失效:

EXPLAIN SELECT * FROM users WHERE age + 1 = 30;

总结

索引失效的核心原因是:查询条件破坏了索引的有序性,或优化器认为全表扫描比索引查询更高效。避免失效的关键是:

  1. 索引字段不参与运算 / 函数;
  2. 遵循联合索引最左前缀原则;
  3. 保证查询条件与字段类型一致;
  4. 避免用 OR 连接非索引字段。

实际开发中,需结合 EXPLAIN 工具和业务数据分布,针对性优化查询语句。

http://www.dtcms.com/a/420989.html

相关文章:

  • 软件 行业门户网站网页版qq登陆入口
  • 做外贸一般上什么网站响应式布局设计
  • 微信公众号创建平台seo百度seo排名优化软件
  • 做创新方法工作的网站如何加强省市级门户网站的建设
  • 1、Order-Service 服务设计规范文档
  • 中信建设证券官方网站计算机类十大含金量证书
  • 多米诺网站建设服务代理网上注册公司
  • 第一次做网站做什么比较好做App和网站 聚马
  • OceanBase数据字典和性能视图
  • 厦门网站建设工作wordpress 下列主题不完整_没有主题样式表和模板.
  • 注册了网站怎么建设怎么看网站做的外链
  • 呼伦贝尔网站开发河北省和城乡建设厅网站
  • 分布式系统与云原生技术个人见解
  • 天津网站搜索排名制作小程序网站源码
  • 手机版网站模板如何做app网站
  • 网站建设培训班价格手机网页制作app
  • 【开题答辩全过程】以 M11289生鲜商城为例,包含答辩的问题和答案
  • 学c还是网站开发百度搜索网站包含的功能
  • 网络服务平台技术包括免费下载百度seo
  • 中山市区做网站公司自助建站网站
  • 织梦网站被挂马怎么处理广东网站营销seo费用
  • 做网站用小公司还是大公司高端产业主要指哪些领域
  • 做暧暧视频免费网站陈晓佳 中信建设有限责任公司
  • 湛江建站公司模板宠物用品销售网站建设和技术现状
  • 众网站做俄罗斯网站
  • 昆明网站建设工作室鹿泉网络推广
  • 在线设计海报的网站站酷网免费素材图库官网
  • 商贸公司网站建设极致发烧电子商务网站建设项目的阶段的划分
  • BIC评分:模型选择的贝叶斯利器与学术传承
  • 网站建设服务市场细分潍坊网站制作企业