今天羣裏有人討論了這個問提,http://weibo.com/1642466057/yAl6d5Izhhtml
並且更巧的是這個內容是我昨晚看的,可是當時只是記住了一個結論,並無仔細去研究mysql優化器的原理。mysql
其實這個問題羣裏說早就有人發現了,能夠參考這個Mysql中對primary key一點選擇改變http://hidba.org/?p=179sql
結論就是老版本的 仍是會走第一索引。5.1.46 的優化器 纔有這個改進shell
順便看了下聚簇索引和二級索引的只是看了下,可是愈來愈發現改進的效果是否是很差啊?我這裏只是表達下本身的見解,請輕拍。mysql優化
個人觀點以下:測試
http://isky000.com/database/innodb_index_structure_basic優化
http://isky000.com/database/myisam-index-structure ui
我沒有仔細看過索引結構的實現,可是這個是簡朝陽的對innodb和myisam的索引樹的介紹。spa
咱們就innodb而言,主索引的葉子節點存儲了key和整行的數據,而二級索引存儲了key和主鍵,若是像羣裏的那個結論,使用二級索引,那麼取全表的時候就會先取key而後再用主鍵去取下整行數據,是否是會增長磁盤的IO啊。.net
這裏有個更詳細的對比圖
http://datalj.blog.163.com/blog/static/342230312012423103049508/
/**
* 20120906 回去看了下innodb那本書
*/
本地作實驗,test表就兩個字段,id和name,id是主鍵,name上有一個二級索引
explain確實是發生了沒有走主鍵而走的二級索引
1 SIMPLE test index ind 33 4 Using index
爲表添加字段state,在作一次全表查詢
此次就木有走索引了,而走的是全表掃描,因此我強烈懷疑微博中提到的數據的準確性。
那麼我就再作一個實驗,把name和state加上一個聯合索引,再作執行
果真如此有走了二級索引
SO....事情的真相如此。。。
對於innodb來講,注意是innodb哦,myisam的索引結構仍是另外一種狀況。
innodb上的二級索引存儲的是索引和主鍵,那麼只要掃描一次二級索引就能夠取出主鍵及索引上列的數據,若是這些數據包括了全表的內容,那麼mysql優化器會在取全表內容是自動走能夠包括全部內容的索引。若是要去取主鍵的時候,由於主鍵的索引結構的葉子節點上只有一個主鍵的值和一個指向全行的指針,那麼想取出全行是上的其餘數據就還要再去進行一次IO,因此mysql就直接用二級索引嘍,固然是在沒有where和order的時候
/**
* 20120906
*/
很差意思,微博的數據我粗心了,原來做者的意圖不是取全表,而是取主鍵。。。我以前有點先入爲主了。
那我再補充一段測試數據吧,微博的原做者是對的。
這是後表結構的二級索引改爲了name
取主鍵列的話走的是二級索引
取二級索引上的列的時候也走的是二級索引
可是取非主鍵和非二級索引的時候就要全表了
我的觀點是,主鍵和二級索引都是直接從葉子節點上取,mysql會優先走二級索引上的列。
這裏推薦幾個資料:
http://knielsen-hq.org/presentations/innodb-clustered-index/innodb-clustered-index.pdf