[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"$f1b300lqgtfmoj":3,"$f250wz8h39yydc":8,"$fh74d94c47b56":29,"$fkpj7wqdcw5wa":33,"$favx0w5wywwcf":44,"toc--659577080-5-5":48},{"description":4,"domain":5,"id":6,"keywords":4,"title":7},"","api.kongjs.com",1,"默认",[9,20,24],{"children":10,"icon":4,"id":11,"linkType":12,"linkUrl":13,"parentId":14,"sort":15,"status":16,"target":17,"title":18,"visible":19},null,"447369447469600768","URL","\u002F","0",0,"1","_self","首页",true,{"children":10,"icon":4,"id":21,"linkType":12,"linkUrl":22,"parentId":14,"sort":15,"status":16,"target":17,"title":23,"visible":19},"447369693859794944","\u002Fnotes","笔记",{"children":10,"icon":4,"id":25,"linkType":26,"linkUrl":27,"parentId":14,"sort":15,"status":16,"target":17,"title":28,"visible":19},"447369977960976384","PAGE","\u002Fabout","关于我",{"category":10,"categoryId":10,"cover":10,"description":4,"fileId":10,"id":30,"publishAt":10,"tags":31,"title":32},"453167887230705664",[],"Mysql面试核心知识",[34,37,40],{"children":10,"description":4,"id":35,"noteId":30,"parentId":14,"sort":15,"status":16,"title":36},"453168082769158144","MySQL索引失效的原因、失效场景",{"children":10,"description":4,"id":38,"noteId":30,"parentId":14,"sort":6,"status":16,"title":39},"453168213975375872","MySQL事务原理、四大隔离级别、MVCC深度详解",{"children":10,"description":4,"id":41,"noteId":30,"parentId":14,"sort":42,"status":16,"title":43},"453168354300010496",2,"B树与B+树 核心原理、完整区别、数据库选型原因",{"content":45,"contentType":46,"description":4,"title":36,"wordCount":47},"# MySQL索引失效的原因\n\nMySQL索引失效本质是**查询语句无法通过索引快速定位数据，优化器判定走索引成本高于全表扫描**，最终放弃索引、触发全表扫描。以下是生产环境中所有高频、核心的索引失效场景，附带原理说明与规避方案。\n\n## 一、索引列运算\u002F函数操作（最高频失效场景）\n\n对**索引字段本身**进行数学运算、函数调用、类型转换，会导致索引失效。因为索引是基于字段原始值构建的，运算后的值无法匹配索引结构，数据库无法使用索引检索。\n\n### 失效示例：\n\n```sql\n-- 索引列做运算\nSELECT * FROM user WHERE age + 10 = 30;\n-- 索引列使用函数\nSELECT * FROM user WHERE DATE(create_time) = '2026-08-30';\n```\n\n### 优化方案：\n\n将运算、函数转移到常量侧，保证索引列裸用。\n\n```sql\nSELECT * FROM user WHERE age = 20;\nSELECT * FROM user WHERE create_time BETWEEN '2026-08-30 00:00:00' AND '2026-08-30 23:59:59';\n```\n\n## 二、隐式类型转换导致失效\n\n查询条件中**索引字段与匹配值类型不一致**，MySQL会自动触发隐式类型转换，等价于对索引列做函数操作，直接失效。\n\n### 核心规则：\n\n- **字符串索引列匹配数字**：索引失效（高频），如 \\`varchar\\` 字段查数字 \\`WHERE phone = 13800138000\\`\n\n- **数字索引列匹配字符串**：索引有效，MySQL会将字符串转数字，不操作索引列\n\n### 失效示例：\n\n```sql\n-- phone 为 varchar 索引字段，传入数字，触发隐式转换，索引失效\nSELECT * FROM user WHERE phone = 13800138000;\n```\n\n### 优化方案：\n\n保持查询值与字段数据类型完全一致，字符串加引号、数字不加引号。\n\n## 三、模糊查询左匹配失效（最左前缀原则破坏）\n\n普通B\\+树索引是**前缀匹配索引**，仅支持右模糊、精准匹配，**左模糊、全模糊**会导致索引失效。\n\n### 失效场景：\n\n```sql\n-- 左模糊、全模糊，索引失效\nSELECT * FROM user WHERE name LIKE '%张三';\nSELECT * FROM user WHERE name LIKE '%张三%';\n```\n\n### 有效场景：\n\n```sql\n-- 右模糊，符合最左前缀，索引生效\nSELECT * FROM user WHERE name LIKE '张三%';\n```\n\n### 优化方案：\n\n需全模糊\u002F左模糊查询时，使用 **全文索引（FULLTEXT）** 或 ES搜索引擎替代普通索引。\n\n## 四、违背联合索引最左前缀原则\n\n联合索引（复合索引）遵循**最左前缀匹配原则**，创建索引 \\`\\(a,b,c\\)\\` 时，查询条件必须包含**最左侧首个字段a**，否则整个联合索引失效。\n\n### 失效示例（无最左字段）：\n\n```sql\n-- 联合索引(a,b,c)，查询仅用b、c，无a，索引完全失效\nSELECT * FROM table WHERE b=1 AND c=2;\n```\n\n### 有效场景：\n\n包含最左字段a，可命中索引（可不用后续字段）：\\`WHERE a=1\\`、\\`WHERE a=1 AND b=2\\`、\\`WHERE a=1 AND c=2\\`\n\n### 补充：\n\n联合索引中间字段断裂，不影响前置索引生效，仅后续字段无法使用索引。例如 \\`WHERE a=1 AND c=2\\`，a字段索引生效，c字段索引失效。\n\n## 五、OR条件使用不当导致索引失效\n\n查询条件中使用 **OR** 时，若**任意一个OR条件字段无索引**，整个语句所有索引全部失效，触发全表扫描。\n\n### 失效示例：\n\n```sql\n-- age有索引，address无索引，OR导致整体索引失效\nSELECT * FROM user WHERE age=18 OR address='北京';\n```\n\n### 优化方案：\n\n- 保证OR关联的**所有字段均建立索引**；\n\n- 复杂OR逻辑使用 \\`UNION ALL\\` 替代。\n\n## 六、NOT、\\!=、\\\u003C\\>、NOT IN 否定查询\n\n对索引列使用否定查询（不等于、不在范围内），MySQL优化器通常会放弃索引。原因：否定条件匹配的数据量大概率极大，全表扫描成本更低。\n\n### 失效示例：\n\n```sql\nSELECT * FROM user WHERE age != 18;\nSELECT * FROM user WHERE age NOT IN (18,20);\nSELECT * FROM user WHERE name \u003C> '张三';\n```\n\n### 特殊情况：\n\n若否定条件匹配数据量极少（表数据量大、命中数据极少），部分高版本MySQL会走索引，但不绝对，属于不稳定场景。\n\n## 七、IS NULL \u002F IS NOT NULL 索引失效\n\nB\\+树索引**不存储NULL值**，因此索引列的空值查询存在失效规则：\n\n- **IS NOT NULL**：大概率索引失效，非空数据占比极高，优化器选择全表扫描；\n\n- **IS NULL**：部分场景可命中索引，但效率极低，不推荐使用。\n\n### 优化方案：\n\n字段设计时**禁止NULL**，默认赋值空字符串、0等默认值，规避空值查询。\n\n## 八、查询数据量过大（索引失效核心场景）\n\nMySQL优化器会计算成本，当查询结果集**超过表总数据的20%\\~30%**时，判定走索引的回表成本高于全表扫描，直接放弃索引。\n\n常见场景：范围查询过大 \\`\\>\\`、\\`\\\u003C\\`、\\`BETWEEN\\` 匹配大量数据、无分页查询全量数据。\n\n### 示例：\n\n一张10万数据的表，查询 \\`WHERE id \\> 1000\\` 匹配8万条数据，索引直接失效。\n\n## 九、索引失效的其他小众场景\n\n### 1\\. 索引过期\u002F统计信息不准确\n\nMySQL依赖索引统计信息判断执行计划，长期未更新统计信息、表频繁增删改，会导致优化器误判，错误放弃索引。可通过 \\`ANALYZE TABLE 表名;\\` 刷新统计信息。\n\n### 2\\. 短索引\u002F前缀索引局限性\n\n对长文本字段建立前缀索引（仅截取前N个字符），查询条件超出截取长度时，无法精准匹配，索引失效。\n\n### 3\\. 强制全表扫描参数\n\n会话\u002F全局开启 \\`IGNORE INDEX\\` 、优化器参数配置异常，会主动禁用索引。\n\n### 4\\. 主键索引特殊场景\n\nInnoDB主键索引为聚簇索引，极少失效，但大批量范围删除、更新时，会触发优化器放弃索引。\n\n## 十、快速排查索引失效的方法\n\n在SQL前加 **EXPLAIN**，查看执行计划：\n\n- **type=ALL**：全表扫描，索引失效；\n\n- **key=NULL**：未使用任何索引；\n\n- **rows** 数值极大：索引未生效。\n\n## 总结：索引失效核心避坑口诀\n\n不运算、不转换、左模糊不行；\n\n    联合索引守前缀、OR字段全索引；\n\n    否定空值少使用、大数据不走索引；\n\n    类型一致是基础、统计信息要新鲜。\n","markdown",3154,{"frontmatter":49,"meta":50,"nodes":153},{},{"title":51,"description":52,"toc":53},"MySQL索引失效的原因","MySQL索引失效本质是查询语句无法通过索引快速定位数据，优化器判定走索引成本高于全表扫描，最终放弃索引、触发全表扫描。以下是生产环境中所有高频、核心的索引失效场景，附带原理说明与规避方案。",{"title":4,"searchDepth":54,"depth":54,"links":55},5,[56,66,77,89,101,109,118,124,131,147,150],{"id":4,"depth":42,"text":57,"children":58},"一、索引列运算\u002F函数操作（最高频失效场景）",[59,63],{"id":60,"depth":61,"text":62},"-",3,"失效示例：",{"id":64,"depth":61,"text":65},"--1","优化方案：",{"id":67,"depth":42,"text":68,"children":69},"-1","二、隐式类型转换导致失效",[70,73,75],{"id":71,"depth":61,"text":72},"--2","核心规则：",{"id":74,"depth":61,"text":62},"--3",{"id":76,"depth":61,"text":65},"--4",{"id":78,"depth":42,"text":79,"children":80},"-2","三、模糊查询左匹配失效（最左前缀原则破坏）",[81,84,87],{"id":82,"depth":61,"text":83},"--5","失效场景：",{"id":85,"depth":61,"text":86},"--6","有效场景：",{"id":88,"depth":61,"text":65},"--7",{"id":90,"depth":42,"text":91,"children":92},"-3","四、违背联合索引最左前缀原则",[93,96,98],{"id":94,"depth":61,"text":95},"--8","失效示例（无最左字段）：",{"id":97,"depth":61,"text":86},"--9",{"id":99,"depth":61,"text":100},"--10","补充：",{"id":102,"depth":42,"text":103,"children":104},"or","五、OR条件使用不当导致索引失效",[105,107],{"id":106,"depth":61,"text":62},"or-",{"id":108,"depth":61,"text":65},"or--1",{"id":110,"depth":42,"text":111,"children":112},"notnot-in","六、NOT、!=、\u003C>、NOT IN 否定查询",[113,115],{"id":114,"depth":61,"text":62},"notnot-in-",{"id":116,"depth":61,"text":117},"notnot-in--1","特殊情况：",{"id":119,"depth":42,"text":120,"children":121},"is-null-is-not-null","七、IS NULL \u002F IS NOT NULL 索引失效",[122],{"id":123,"depth":61,"text":65},"is-null-is-not-null-",{"id":125,"depth":42,"text":126,"children":127},"-4","八、查询数据量过大（索引失效核心场景）",[128],{"id":129,"depth":61,"text":130},"--11","示例：",{"id":132,"depth":42,"text":133,"children":134},"-5","九、索引失效的其他小众场景",[135,138,141,144],{"id":136,"depth":61,"text":137},"-_1","1. 索引过期\u002F统计信息不准确",{"id":139,"depth":61,"text":140},"-_2","2. 短索引\u002F前缀索引局限性",{"id":142,"depth":61,"text":143},"-_3","3. 强制全表扫描参数",{"id":145,"depth":61,"text":146},"-_4","4. 主键索引特殊场景",{"id":148,"depth":42,"text":149},"-6","十、快速排查索引失效的方法",{"id":151,"depth":42,"text":152},"-7","总结：索引失效核心避坑口诀",[154,158,167,170,177,180,189,191,194,199,201,208,210,226,228,233,235,238,240,251,253,258,260,265,267,274,276,287,289,294,296,299,301,304,306,317,319,324,326,338,340,343,345,350,352,355,357,364,378,380,387,389,392,395,397,400,402,404,407,409,412,414,417,419,422,424,431,451,453,456],[155,156,51],"h1",{"id":157},"mysql",[159,160,161,162,166],"p",{},"MySQL索引失效本质是",[163,164,165],"strong",{},"查询语句无法通过索引快速定位数据，优化器判定走索引成本高于全表扫描","，最终放弃索引、触发全表扫描。以下是生产环境中所有高频、核心的索引失效场景，附带原理说明与规避方案。",[168,169,57],"h2",{"id":4},[159,171,172,173,176],{},"对",[163,174,175],{},"索引字段本身","进行数学运算、函数调用、类型转换，会导致索引失效。因为索引是基于字段原始值构建的，运算后的值无法匹配索引结构，数据库无法使用索引检索。",[178,179,62],"h3",{"id":60},[181,182,184],"pre",{"language":183},"sql",[185,186,188],"code",{"class":187},"language-sql","-- 索引列做运算\nSELECT * FROM user WHERE age + 10 = 30;\n-- 索引列使用函数\nSELECT * FROM user WHERE DATE(create_time) = '2026-08-30';",[178,190,65],{"id":64},[159,192,193],{},"将运算、函数转移到常量侧，保证索引列裸用。",[181,195,196],{"language":183},[185,197,198],{"class":187},"SELECT * FROM user WHERE age = 20;\nSELECT * FROM user WHERE create_time BETWEEN '2026-08-30 00:00:00' AND '2026-08-30 23:59:59';",[168,200,68],{"id":67},[159,202,203,204,207],{},"查询条件中",[163,205,206],{},"索引字段与匹配值类型不一致","，MySQL会自动触发隐式类型转换，等价于对索引列做函数操作，直接失效。",[178,209,72],{"id":71},[211,212,213,220],"ul",{},[214,215,216,219],"li",{},[163,217,218],{},"字符串索引列匹配数字","：索引失效（高频），如 `varchar` 字段查数字 `WHERE phone = 13800138000`",[214,221,222,225],{},[163,223,224],{},"数字索引列匹配字符串","：索引有效，MySQL会将字符串转数字，不操作索引列",[178,227,62],{"id":74},[181,229,230],{"language":183},[185,231,232],{"class":187},"-- phone 为 varchar 索引字段，传入数字，触发隐式转换，索引失效\nSELECT * FROM user WHERE phone = 13800138000;",[178,234,65],{"id":76},[159,236,237],{},"保持查询值与字段数据类型完全一致，字符串加引号、数字不加引号。",[168,239,79],{"id":78},[159,241,242,243,246,247,250],{},"普通B+树索引是",[163,244,245],{},"前缀匹配索引","，仅支持右模糊、精准匹配，",[163,248,249],{},"左模糊、全模糊","会导致索引失效。",[178,252,83],{"id":82},[181,254,255],{"language":183},[185,256,257],{"class":187},"-- 左模糊、全模糊，索引失效\nSELECT * FROM user WHERE name LIKE '%张三';\nSELECT * FROM user WHERE name LIKE '%张三%';",[178,259,86],{"id":85},[181,261,262],{"language":183},[185,263,264],{"class":187},"-- 右模糊，符合最左前缀，索引生效\nSELECT * FROM user WHERE name LIKE '张三%';",[178,266,65],{"id":88},[159,268,269,270,273],{},"需全模糊\u002F左模糊查询时，使用 ",[163,271,272],{},"全文索引（FULLTEXT）"," 或 ES搜索引擎替代普通索引。",[168,275,91],{"id":90},[159,277,278,279,282,283,286],{},"联合索引（复合索引）遵循",[163,280,281],{},"最左前缀匹配原则","，创建索引 `(a,b,c)` 时，查询条件必须包含",[163,284,285],{},"最左侧首个字段a","，否则整个联合索引失效。",[178,288,95],{"id":94},[181,290,291],{"language":183},[185,292,293],{"class":187},"-- 联合索引(a,b,c)，查询仅用b、c，无a，索引完全失效\nSELECT * FROM table WHERE b=1 AND c=2;",[178,295,86],{"id":97},[159,297,298],{},"包含最左字段a，可命中索引（可不用后续字段）：`WHERE a=1`、`WHERE a=1 AND b=2`、`WHERE a=1 AND c=2`",[178,300,100],{"id":99},[159,302,303],{},"联合索引中间字段断裂，不影响前置索引生效，仅后续字段无法使用索引。例如 `WHERE a=1 AND c=2`，a字段索引生效，c字段索引失效。",[168,305,103],{"id":102},[159,307,308,309,312,313,316],{},"查询条件中使用 ",[163,310,311],{},"OR"," 时，若",[163,314,315],{},"任意一个OR条件字段无索引","，整个语句所有索引全部失效，触发全表扫描。",[178,318,62],{"id":106},[181,320,321],{"language":183},[185,322,323],{"class":187},"-- age有索引，address无索引，OR导致整体索引失效\nSELECT * FROM user WHERE age=18 OR address='北京';",[178,325,65],{"id":108},[211,327,328,335],{},[214,329,330,331,334],{},"保证OR关联的",[163,332,333],{},"所有字段均建立索引","；",[214,336,337],{},"复杂OR逻辑使用 `UNION ALL` 替代。",[168,339,111],{"id":110},[159,341,342],{},"对索引列使用否定查询（不等于、不在范围内），MySQL优化器通常会放弃索引。原因：否定条件匹配的数据量大概率极大，全表扫描成本更低。",[178,344,62],{"id":114},[181,346,347],{"language":183},[185,348,349],{"class":187},"SELECT * FROM user WHERE age != 18;\nSELECT * FROM user WHERE age NOT IN (18,20);\nSELECT * FROM user WHERE name \u003C> '张三';",[178,351,117],{"id":116},[159,353,354],{},"若否定条件匹配数据量极少（表数据量大、命中数据极少），部分高版本MySQL会走索引，但不绝对，属于不稳定场景。",[168,356,120],{"id":119},[159,358,359,360,363],{},"B+树索引",[163,361,362],{},"不存储NULL值","，因此索引列的空值查询存在失效规则：",[211,365,366,372],{},[214,367,368,371],{},[163,369,370],{},"IS NOT NULL","：大概率索引失效，非空数据占比极高，优化器选择全表扫描；",[214,373,374,377],{},[163,375,376],{},"IS NULL","：部分场景可命中索引，但效率极低，不推荐使用。",[178,379,65],{"id":123},[159,381,382,383,386],{},"字段设计时",[163,384,385],{},"禁止NULL","，默认赋值空字符串、0等默认值，规避空值查询。",[168,388,126],{"id":125},[159,390,391],{},"MySQL优化器会计算成本，当查询结果集**超过表总数据的20%~30%**时，判定走索引的回表成本高于全表扫描，直接放弃索引。",[159,393,394],{},"常见场景：范围查询过大 `>`、`\u003C`、`BETWEEN` 匹配大量数据、无分页查询全量数据。",[178,396,130],{"id":129},[159,398,399],{},"一张10万数据的表，查询 `WHERE id > 1000` 匹配8万条数据，索引直接失效。",[168,401,133],{"id":132},[178,403,137],{"id":136},[159,405,406],{},"MySQL依赖索引统计信息判断执行计划，长期未更新统计信息、表频繁增删改，会导致优化器误判，错误放弃索引。可通过 `ANALYZE TABLE 表名;` 刷新统计信息。",[178,408,140],{"id":139},[159,410,411],{},"对长文本字段建立前缀索引（仅截取前N个字符），查询条件超出截取长度时，无法精准匹配，索引失效。",[178,413,143],{"id":142},[159,415,416],{},"会话\u002F全局开启 `IGNORE INDEX` 、优化器参数配置异常，会主动禁用索引。",[178,418,146],{"id":145},[159,420,421],{},"InnoDB主键索引为聚簇索引，极少失效，但大批量范围删除、更新时，会触发优化器放弃索引。",[168,423,149],{"id":148},[159,425,426,427,430],{},"在SQL前加 ",[163,428,429],{},"EXPLAIN","，查看执行计划：",[211,432,433,439,445],{},[214,434,435,438],{},[163,436,437],{},"type=ALL","：全表扫描，索引失效；",[214,440,441,444],{},[163,442,443],{},"key=NULL","：未使用任何索引；",[214,446,447,450],{},[163,448,449],{},"rows"," 数值极大：索引未生效。",[168,452,152],{"id":151},[159,454,455],{},"不运算、不转换、左模糊不行；",[181,457,458],{},[185,459,460],{},"联合索引守前缀、OR字段全索引；\n\n否定空值少使用、大数据不走索引；\n\n类型一致是基础、统计信息要新鲜。"]