mysql索引分析

索引场景分析:
    某个表有(C1,C2,C3,C4),以下只能使用联合索引的C1,C2,C3部分
    A.where C1=x and C2=x and C4>x and C3=x
    B.where C1=x and C2=x and C4=x order by C3
    C.where C1=x and C4=x group by C3,C2
    D.where C1=? and C5=? order by C3,C2
    E.where C1=? and C2=? and C5=? order by C2,C3
    
    A.where C1=x and C2=x and C4>x and C3>x
    Mysql内部会优化sql语句,优化结果:where C1=x and C2=x and C3=x and C4>x ,所以都能用上
    
    B.where C1=x and C2=x and C4=x order by C3  C1能,C2能,C3能,  C4用不上
    
    D.where C1=? and C5=? order by C3,C2    C1能,C2能,C3能
    
解决思路B-Tree索引的左前缀匹配原则
    Myisam,Innodb默认使用B-Tree索引
    B-Tree索引:排好序的可以快速查找的数据结构[排好序,可快速查找,可以范围查找]
    Hash索引:在memory表里,默认是hash索引,时间复杂度是o(1)
    [hash值随机,在磁盘上放置也是随机,无法快速定位,无法范围优化]
    
单个索引意义不大.开发中大部分的时候使用的是多列索引号

多列索引号要想利用上必须满足最左前缀原则
分析index(A,B,C)
where A=3   A能
where A=3 and B=5    A能,B能
where A=3 and B=5 and C=4    A能,B能,C能
where B=3 or C=4    没有使用索引[违反了最左前缀原则]
where A=3 or C=4    A能,B不能,C不能[中间断层了]
where A=3 and B>10 and C=4    A能,B能,C不能[B是范围,无法定位C]
where A=3 and B like 'foo%' and C=10    A能,B能,C不能,[同上]




实战:
mysql> explain select name,age from person where  name LIKE '%pttxs%' and age >= 49\G;
*************************** 1. row ***************************
           id: 1
  select_type: SIMPLE
        table: person
         type: index
possible_keys: NULL
          key: name_age
      key_len: 128
          ref: NULL
         rows: 4114293
        Extra: Using where; Using index
1 row in set (0.00 sec)

ERROR:
No query specified

mysql> explain select name,age from person where  name LIKE 'pttxs%' and age >= 49\G;
*************************** 2. row ***************************
           id: 1
  select_type: SIMPLE
        table: person
         type: range
possible_keys: name_age
          key: name_age
      key_len: 128
          ref: NULL
         rows: 1016160
        Extra: Using where; Using index
1 row in set (0.00 sec)

其一.这里分析了两句select查询,差别在于1.row是name LIKE '%pttxs%'    2.row name LIKE 'pttxs%',
显然1.row第一个没有用到索引,从possible_keys: NULL可以看出
其二.从rows可以看出1. row>>>>rows: 4114293    2.row>>>rows: 1016160可见1. row造成全表扫描了


分析2.
mysql> explain select name,age from person where  name LIKE 'pttxs%' and age >= 49 order by phone \G;
*************************** 1. row ***************************
           id: 1
  select_type: SIMPLE
        table: person
         type: ALL
possible_keys: name_age
          key: NULL
      key_len: NULL
          ref: NULL
         rows: 4114293
        Extra: Using where; Using filesort
1 row in set (0.00 sec)

ERROR:
No query specified
注意:这里phone没有建立索引,没有排好序, Using filesort说明在文件或者内存中进行了2次排序,而且没有利用索引


你可能感兴趣的:(mysql索引分析)