MySQL 索引的匹配類型

來源:互聯網
上載者:User

標籤:mysql 索引   匹配類型   


MySQL 索引的匹配類型


/*


建立測試表

drop table  t_index ;

create table t_index(

tid  int  not null PRIMARY key  auto_increment ,

tname varchar(100) not null ,

tage TINYINT  default 0 ,

tadd varchar(100) default  ‘‘ ,

tel int default  0,

tmob varchar(20) DEFAULT ‘‘ ,

tsfz varchar(100) default  ‘‘ 

ENGINE=InnoDB DEFAULT CHARSET=utf8;


插入資料:


insert into  t_index(tname,tage,tadd,tel,tmob,tsfz)

VALUES(‘張三風‘,120,‘武當山‘ ,18099001122,‘012-46319976‘,‘‘) ;

insert into  t_index(tname,tage,tadd,tel,tmob,tsfz)

VALUES(‘朱元璋‘,56,‘北京‘ ,18112401122,‘012-40119976‘,‘‘) ;

insert into  t_index(tname,tage,tadd,tel,tmob,tsfz)

VALUES(‘楊過‘,25,‘武漢‘ ,18099112122,‘012-46340116‘,‘‘) ;

insert into  t_index(tname,tage,tadd,tel,tmob,tsfz)

VALUES(‘郭靖‘,45,‘長沙‘ ,13149001122,‘012-46900176‘,‘‘) ;

insert into  t_index(tname,tage,tadd,tel,tmob,tsfz)

VALUES(‘黃老邪‘,100,‘河北‘ ,13129001122,‘012-49001976‘,‘‘) ;

insert into  t_index(tname,tage,tadd,tel,tmob,tsfz)

VALUES(‘周伯通‘,102,‘河南‘ ,15679001122,‘012-46319001‘,‘‘) ;

insert into  t_index(tname,tage,tadd,tel,tmob,tsfz)

VALUES(‘洪七公‘,78,‘合肥‘ ,11243001122,‘012-46319976‘,‘‘) ;

insert into  t_index(tname,tage,tadd,tel,tmob,tsfz)

VALUES(‘歐陽峰‘,67,‘廣西‘ ,13214001122,‘012-14009976‘,‘‘) ;

insert into  t_index(tname,tage,tadd,tel,tmob,tsfz)

VALUES(‘歐陽可‘,27,‘深圳‘ ,15123001122,‘012-46314006‘,‘‘) ;

insert into  t_index(tname,tage,tadd,tel,tmob,tsfz)

VALUES(‘尼瑪‘,10,‘上海‘ ,13125001122,‘012-41400976‘,‘‘) ;

insert into  t_index(tname,tage,tadd,tel,tmob,tsfz)

VALUES(‘楊康‘,30,‘西藏‘ ,15798001122,‘012-46311400‘,‘‘) ;




建立一個多列索引

alter table t_index 

add  key (tname,tage,tadd)


可以使用B-tree的查詢類型:


1.全值匹配:查詢中包含多列索引中德所有列並且在查詢中充分利用到了索引讀取資料。

這個情況存在於多列索引中的,對於單列索引都是全值匹配的。

在多列索引中可能由於某些原因不能做到全值匹配,只能做到部分列匹配。

例如:


mysql> explain  select * from t_index where tname=‘張三風‘ and  tage=120 and  tadd=‘武當山‘ ;

+----+-------------+---------+------+---------------+-------+---------+-------------------+------+-------------+

| id | select_type | table   | type | possible_keys | key   | key_len | ref               | rows | Extra       |

+----+-------------+---------+------+---------------+-------+---------+-------------------+------+-------------+

|  1 | SIMPLE      | t_index | ref  | tname         | tname | 607     | const,const,const |    1 | Using where |

+----+-------------+---------+------+---------------+-------+---------+-------------------+------+-------------+


該查詢使用的就是全值匹配,在查詢中使用到了多列索引中的全部列

注意:要是做到全值匹配,那麼多列索引中的最後一列的前面的所有列必須給出準確的值,不能是範圍值,

否則就是變成了了部分值匹配,


2.部分值匹配:查詢中沒有完全利用到多列索引中的列。

查詢中使用的列都包含在多列索引中,但是有部分列使用了範圍值(索引中最後一列除外)


sql11

mysql> explain   select * from t_index where tname=‘張三風‘ and  tage  like  ‘12%‘ and  tadd=‘武當山‘ ;

+----+-------------+---------+------+---------------+-------+---------+-------+------+-------------+

| id | select_type | table   | type | possible_keys | key   | key_len | ref   | rows | Extra       |

+----+-------------+---------+------+---------------+-------+---------+-------+------+-------------+

|  1 | SIMPLE      | t_index | ref  | tname         | tname | 302     | const |    3 | Using where |

+----+-------------+---------+------+---------------+-------+---------+-------+------+-------------+


sql2

mysql> explain   select * from t_index where tname=‘張三風‘ and  tage = 120  and  tadd like  ‘武當%‘ ;

+----+-------------+---------+-------+---------------+-------+---------+------+------+-------------+

| id | select_type | table   | type  | possible_keys | key   | key_len | ref  | rows | Extra       |

+----+-------------+---------+-------+---------------+-------+---------+------+------+-------------+

|  1 | SIMPLE      | t_index | range | tname         | tname | 607     | NULL |    1 | Using where |

+----+-------------+---------+-------+---------------+-------+---------+------+------+-------------+


sql3

mysql>  explain   select * from t_index where tname=‘張三風‘ and  tage  > 115 and  tadd=‘武當山‘ ;

+----+-------------+---------+-------+---------------+-------+---------+------+------+-------------+

| id | select_type | table   | type  | possible_keys | key   | key_len | ref  | rows | Extra       |

+----+-------------+---------+-------+---------------+-------+---------+------+------+-------------+

|  1 | SIMPLE      | t_index | range | tname         | tname | 304     | NULL |    2 | Using where |

+----+-------------+---------+-------+---------------+-------+---------+------+------+-------------+


sql4

mysql> explain  select * from t_index where tname=‘張三風‘ and  tage  < 110 and  tadd=‘武當山‘ ;

+----+-------------+---------+------+---------------+------+---------+------+------+-------------+

| id | select_type | table   | type | possible_keys | key  | key_len | ref  | rows | Extra       |

+----+-------------+---------+------+---------------+------+---------+------+------+-------------+

|  1 | SIMPLE      | t_index | ALL  | tname         | NULL | NULL    | NULL |   13 | Using where |

+----+-------------+---------+------+---------------+------+---------+------+------+-------------+


sql1中tage使用模糊查詢查詢導致該查詢只使用到了索引的第一列(以前長期認為此種查詢會使用到第一列和第二列)

sql2中tadd使用了範圍值,但是tadd是索引中的最後一列,查詢還是使用了全值匹配。

sql3中tage使用了範圍值,從執行計畫可以看到查詢使用了索引的第一列和第二列

sql4使用了全表掃描,沒有使用任何的索引掃描,根據索引使用規則,該查詢完全能走索引掃描的,但是為什麼沒有走呢。

我查詢結果公布下,估計會出乎意料之外。

mysql>   select * from t_index where tname=‘張三風‘ and  tage  < 110 and  tadd=‘武當山‘ ;

Empty set (0.00 sec)

查詢出來是空值。根據我們的常規思維,sql4的可以使用到多列索引的第一列和第二列。這一點有點和SQLServer不一樣,

這裡提一下,謹防上當受騙。



本文出自 “SQLServer MySQL” 部落格,謝絕轉載!

MySQL 索引的匹配類型

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.