(1)案例1
    SQL语句 select * from table where x1=xx and x2>=xx ,这样一个SQL要查一个表,用了x1和x2两个字段,建立了联合索引,但是万一 建立了 (x1,x3) 和 (x2,x4) 两个索引, 这个SQL只能选择其中一个索引去用,此时会选择哪一个呢?
    这里MySQL负责生成执行计划的查询优化器,一般会选择在索引里扫描行数比较少的那个条件。比如x1=xx,在索引里只要做等值比较,扫描数据比较少,那么可能会挑选x1 索引,做一个 索引树的查询,在执行计划里,其实就是一个ref计划,找到几条数据之后,接着做一个回表,回到聚簇索引里去查询每条数据的完整数据,接着加载到内存里,根据每条数据的x2字段值,根据 x2>=xx 条件做一个筛选。
    这就是面对两个字段都能用索引是如何选择以及如何进行处理的方式。

    (2)案例2
    SQL语句 select * from table where x1=xx and c1=xx and c2>=xx and c3 is NOT NULL ,其实平时会经常写出类似这样的SQL语句,就是一个SQL的所有筛选条件里,就一个x1是有 索引的,其他字段都是没有索引的,这种情况非常常见,一般在写好一个系统后,针对所有SQL分析时,不可能针对所有SQL里的每一个where里的字段都加一个索引,这是不现实的,最终我们只能在 所有的SQL语句里,抽取部分经常在where里用到的字段来设计两三个联合索引。
    所以这种情况下,必然很多SQL语句里,可能where后的条件有好几个,结果就一个字段可以用到索引,此时查询优化器生成的执行计划,就会针对x1字段走一个 ref 访问,直接通过x1字段 的索引树快速查找到指定的一批数据。
    接着对这批数据都回表到聚簇索引里去,把每条数据完整的字段都查出来,然后加载到内存里去。接着就可以针对这批数据的c1,c2,c3 字段按照条件进行筛选和过滤,最后拿到符合条件的数据。
    所以x1索引的设计,必然尽可能要让x1=xx这个条件在索引树里查找出来的数据量比较少,才能保证后续的性能比较高。

    知识点:or不一定失效,需要结合数据的筛选粒度来分析。实际的需要看查询优化器的优化还有数据量的大小都会是影响因素。