为什么where条件中使用or索引不起作用?where条件中使用or,索引就会失效,会造成全表扫描    是误区

一,要求使用的所有字段,都必须建立索引。

二,数据量太少,制定执行计划时发现全表扫描比索引查找更快。

三,确保mysql版本5.0以上,且查询优化器开启了index_merge_union=on, 也就是变量optimizer_switch里存在index_merge_union且为on

Note:Use of Index Merge is subject to the value of the index_mergeindex_merge_intersection,index_merge_union, and index_merge_sort_union flags of the optimizer_switch system variable. See Section 8.9.2, “Switchable Optimizations”. By default, all those flags are on
          合并索引是否使用取决于优化器开关的系统参数值,默认情况下这些参数值都为on,如果需要重新设置,请参照Section 8.9.2, “Switchable Optimizations”

Note :EXPALIN 看到type列的值为ALL,意味着MYSQL使用全表扫描解析查询MYSQL 使用全表扫描去解析查询通常有如下几种条件:

  • 该表非常小,全表扫描比索引查找要快。对于少于10行和短行长度的表来说,这很常见。

  •  ON 或 WHERE条件句中不存在可用的索引约束简单理解为条件句中根本不包含索引列或者包含索引列但是由于条件限制导致索引失效。

  • 将索引列与常量值做比较,并且MYSQL 已经基于索引树计算出这个常量值在表数据中存在的概率很大以至于全表扫描更快 。详情见 Section 8.2.1.1, “WHERE Clause Optimization”

  • 类似于上一情况,使用唯一性较低的列作为索引列,这种情况下,MYSQL假定全表扫描比索引查找更快。

例子:

      找一含几千万数据的表, explain了一下or查询

# id是主键, user_id是普通索引
explain SELECT * from t WHERE id = 100000 or user_id = 'c7b6752c37b111e6a7d705b57e583e2e';
idselect_typetabletypepossible_keyskeykey_lenrefrowsExtra
1SIMPLEtindex_mergePRIMARY,t_useridPRIMARY,t_userid4,123 2Using union(PRIMARY,t_userid); 
Type : index_merge  表明使用了合并索引

Extra :Using union(PRIMARY,t_userid);  表明合并为index_merge 索引使用了 union 算法



Logo

更多推荐