InnoDB 和MyISAM是MySQL中最常见的两种存储引擎。每种存储引擎都可以拥有不同数量和类型的索引,但它们的索引失效条件略有不同。接下来会依次解释两者的索引失效情况。
如果表中只有一个二级索引,它将不会对插入、更新或者除空值(没有任何条件判断)的记录操作产生失效。
以下是可能导致MyISAM和INEINN不分存储索引失效条件及原因:
=== MyISAM ===
二级索引失败条件:
```
· 数据页面分割导致一个索引包含连续行转为不连续。
· 在查询和索引字段的 order by 中有隐藏类型转换造成使用不同取值转换(通常指字符类型直接与数值比较)。注意不同存储引擎对于索引查找是有默认排序的,因此注意 select field1,... in(c1, c2, ...) 或 order by field1, ...。
```
全表扫描且不含有任何索引失败的可能原因
```
· 数据页离散。当一个包含全文内容的 MyISAM 大表内容由于数据库中的自由空间不足等原因从“数据”文件里移动到数据“索引文件”下,并且同时“回库”配置显为空
(mysql system variable select_convert或group_convert设置为 loose or any_letter后),则会导致全表回表操作导致性能出现下降,全检索会失效。
```
其他索引失效或部分失效
```
索引的使用和选择受 mysql_query_plan()函数支配。mysql_query_planning()过程中一些统计信息可能未能收集,则可能存在以下几种问题,
可能会使得索引不使用从而导致查询计划失效。
· 相关列没有被引用或者全部替换为空或者重复取值的 constant value:具体可以观察 execuse 或者 query plan中
select * froom a Where col1=1和select *from b ... Join a on a1 col=b where a1,col1...
- Join( join ... ): 在 join的时候对 col 表达式重新赋值,会导致原有 index 失效或者部分失效.
-- on 、 use: on join 操作会重新给索引列在 a 与 rance1 进行 join 或者 range on操作时 a,
-- rance1 进行 on on rance2 等 ... 进行 on 操作
where <=> range conditions not used:
mysql_select() 对 WHERE a <=> ? 这个类似常数值进行 on on 的等值过滤判断的。
```
注:由于 IN(), OR 查询在 MyISAM 中会从左到右进行数据过滤,所以 ...in() select col1, col1... from table where age is null 时,只要数据表是 MyISAM.那么索引都会失效掉!... 展开详请