我們平常所說的索引,如果沒有特別指明,都是指b+樹結構組織的b-tree索引。其中聚集索引,次要索引,覆蓋索引,復合索引,字首索引,唯一索引預設都是使用b+樹索引,統稱索引。當然,除了b+樹這種型別的索引之外,還有哈稀索引(hash index)等。
這裡主要討論一下innodb b-tree索引的使用,不提設計,只管使用。b-tree索引主要作用於where和order by子句。這裡討論的均在mysql-server-5.1.38測試
[php]
create table `friends` (
`id` int(10) unsigned not null auto_increment,
`uid` bigint(20) unsigned not null default '0',
`fuid` bigint(20) unsigned not null default '0',
`fname` varchar(50) not null default '',
`fpicture` varchar(150) not null default '',
`f***` tinyint(1) not null default '0',
`status` tinyint(1) not null default '0',
primary key (`id`)
) engine=innodb auto_increment=1 default charset=utf8;
alter table `friends` add index uid_fuid (uid, fuid);
[/php]
1.如果索引了多列,要遵守最左字首法則。所謂最左前列,指的是查詢從索引的最左前列開始,並且不跳過索引中的列。
第2條語句,從索引的第二列開始查詢,使用索引失敗,導致mysql採用all訪問策略,即全表查詢.在開發中,應該盡量避免全表查詢。
2.當mysql一旦估計檢查的行數可能會」太多」,範圍查詢優化將不會被使用。
第2條語句使用了全表查詢,它與第1條語句唯一的區別在於需要檢查的行數遠遠多於第1條語句。在應用中,可能不會碰到這麼大的查詢,但是應該避免這樣的查詢出現: select uid from users where registered < 1295001384
3.索引列不應該作為表示式的一部分,即也不能在索引列上使用函式
第2和3條語句都有使用表示式,索引派不上用場。
4.盡量借用覆蓋索引,減少select * from …語句使用
第1句extra中使用了using index表示使用了覆蓋索引。第3句也使用了覆蓋索引,雖然id不在索引uid_fuid索引列中,但是innodb二次索引(second index)葉子頁的值就是pk值,不同於myisam。extra部分的using index表示應用了索引,不要跟type中的index混淆。第2句沒有使用覆蓋索引,因為f***不在索引中。
5.order by子句,盡量使用index方式排序,避免使用filesort方式排序
mysql支援二種方式的排序,filesort和index,後者效率高,它指mysql掃瞄索引本身完成排序。filesort方式效率較低。order by滿足以下情況,會使用index方式排序:
a)order by 語句使用索引最左前列。參見第1句
b)使用where子句與order by子句條件列組合滿足索引最左前列。參見第2句.
以下情況,會使用filesort方式的查詢
a)檢查的行數過多,且沒有使用覆蓋索引。第3句,雖然跟第2句一樣,order by使用了索引最左前列uid,但依然使用了filesort方式排序,因為status並不在索引中,所以沒辦法只掃瞄索引。
b)使用了不同的索引,mysql每回只採用乙個索引.第4句,order by出現二個索引,分別是uid_fuid和聚集索引(pk)
c)對索引列同時使用了asc和desc。 通過where語句將order by中索引列轉為常量,則除外。第5句,和第6句在order by子句中,都出現了asc和desc排序,但是第5句卻使用了filesort方式排序,是因為第6句where uid取出排序需要的資料,mysql將其轉為常量,它的ref列為const。
d)where語句與order by語句,使用了不同的索引。參見第8句。
e)where語句或者order by語句中索引列使用了表示式,包括函式表示式。參見第9句
f)where 語句與order by語句組合滿足最左字首,但where語句中使用了條件查詢。查見第10句,雖然where與order by構成了索引最左有綴的條件,但是where子句中使用的是條件查詢。
g)order by子句中加入了非索引列,且非索引列不在where子句中。
h)order by或者它與where組合沒有滿足索引最左前列。參見第11句和12句,where與order by組合,不滿足索引最左前列. (uid, f***)跳過了fuid
i)當使用left join,使用右邊的表字段排序。參見第13句,儘管user.uid是pk,依然會使用filesort排序。
6.慎用left join語句,避免建立臨時表使用left join語句的時候,避免出現建立臨時表。盡量不要用left join,分而治之。非要使用的時候,要詢問自己是不是真要必須要使用。
7.高選擇性索引列。 盡量使用高選擇性的過引來過濾資料。高選擇性指cardinality/#t越接近1,選擇性越高,其中cardinality指表中索引列不重複值(行)的總數。pk和唯一索引,具有最高的選擇性,即1。推薦可選性達到20%以上。
這裡有二個索引可供使用,而mysql選擇primary,是因為它具有更高的選擇性。
8.謹防where子句中的or。where語句使用or,且沒有使用覆蓋索引,會進行全表掃瞄。應該盡量避免這樣or語句。盡量使用union代替or
第1句雖然使用了索引,但是查行時間依然不可以恭維,mysql要檢查的行很多,但是返回的行卻很少.extra中的using where表示需要通過where子句扔棄不需要的資料行。
9.limit與覆蓋索引limit子句,使用覆蓋索引時比沒有使用覆蓋索引會快很多
mysql索引 使用筆記 mysql索引筆記
mysql索引 一 索引的優缺點 優點 1.通過建立唯一索引,可以保證資料庫表中每一行的唯一性。2.可以大大加快查詢速度,這是建立索引的最主要原因 4.在使用分組和排序子句進行資料查詢時,也可以顯著減少查詢中分組和查詢的時間 缺點 1.建立索引和維護索引要耗費時間,並且隨著資料量的增加所耗費的時間也...
mysql使用筆記
mysql安裝 bin mysqld initialize insecure user mysql basedir usr local mysql datadir usr local mysql data mkdir p var run mysqld chown mysql mysql var ru...
MySQL使用筆記
刪除修改 查詢元資料操作 表結構調整 許可權管理 字符集設定 資料匯入和匯出 匯入資料 遠端連線mysql 資料庫備份和複製 mysql 程序資訊 編碼集問題 insert into ticket info buyer openid,ticket date values 000751a016bdbf...