關(guān)于MySQL索引的好處,如果正確合理設(shè)計(jì)并且使用索引的MySQL是一輛蘭博基尼的話,那么沒(méi)有設(shè)計(jì)和使用索引的MySQL就是一個(gè)人力三輪車(chē)。對(duì)于沒(méi)有索引的表,單表查詢(xún)可能幾十萬(wàn)數(shù)據(jù)就是瓶頸,而通常大型網(wǎng)站單日就可能會(huì)產(chǎn)生幾十萬(wàn)甚至幾百萬(wàn)的數(shù)據(jù),沒(méi)有索引查詢(xún)會(huì)變的非常緩慢。還是以WordPress來(lái)說(shuō),其多個(gè)數(shù)據(jù)表都會(huì)對(duì)經(jīng)常被查詢(xún)的字段添加索引,比如wp_comments表中針對(duì)5個(gè)字段設(shè)計(jì)了BTREE索引。
一個(gè)簡(jiǎn)單的對(duì)比測(cè)試
以我去年測(cè)試的數(shù)據(jù)作為一個(gè)簡(jiǎn)單示例,20多條數(shù)據(jù)源隨機(jī)生成200萬(wàn)條數(shù)據(jù),平均每條數(shù)據(jù)源都重復(fù)大概10萬(wàn)次,表結(jié)構(gòu)比較簡(jiǎn)單,僅包含一個(gè)自增ID,一個(gè)char類(lèi)型,一個(gè)text類(lèi)型和一個(gè)int類(lèi)型,單表2G大小,使用MyIASM引擎。開(kāi)始測(cè)試未添加任何索引。
執(zhí)行下面的SQL語(yǔ)句:
| mysql> SELECT id,FROM_UNIXTIME(time) FROM article WHERE a.title='測(cè)試標(biāo)題' |
查詢(xún)需要的時(shí)間非常恐怖的,如果加上聯(lián)合查詢(xún)和其他一些約束條件,數(shù)據(jù)庫(kù)會(huì)瘋狂的消耗內(nèi)存,并且會(huì)影響前端程序的執(zhí)行。這時(shí)給title字段添加一個(gè)BTREE索引:
| mysql> ALTER TABLE article ADD INDEX index_article_title ON title(200); |
再次執(zhí)行上述查詢(xún)語(yǔ)句,其對(duì)比非常明顯:
MySQL索引的概念
索引是一種特殊的文件(InnoDB數(shù)據(jù)表上的索引是表空間的一個(gè)組成部分),它們包含著對(duì)數(shù)據(jù)表里所有記錄的引用指針。更通俗的說(shuō),數(shù)據(jù)庫(kù)索引好比是一本書(shū)前面的目錄,能加快數(shù)據(jù)庫(kù)的查詢(xún)速度。上述SQL語(yǔ)句,在沒(méi)有索引的情況下,數(shù)據(jù)庫(kù)會(huì)遍歷全部200條數(shù)據(jù)后選擇符合條件的;而有了相應(yīng)的索引之后,數(shù)據(jù)庫(kù)會(huì)直接在索引中查找符合條件的選項(xiàng)。如果我們把SQL語(yǔ)句換成“SELECT * FROM article WHERE id=2000000”,那么你是希望數(shù)據(jù)庫(kù)按照順序讀取完200萬(wàn)行數(shù)據(jù)以后給你結(jié)果還是直接在索引中定位呢?上面的兩個(gè)圖片鮮明的用時(shí)對(duì)比已經(jīng)給出了答案(注:一般數(shù)據(jù)庫(kù)默認(rèn)都會(huì)為主鍵生成索引)。
索引分為聚簇索引和非聚簇索引兩種,聚簇索引是按照數(shù)據(jù)存放的物理位置為順序的,而非聚簇索引就不一樣了;聚簇索引能提高多行檢索的速度,而非聚簇索引對(duì)于單行的檢索很快。
MySQL索引的類(lèi)型
1. 普通索引
這是最基本的索引,它沒(méi)有任何限制,比如上文中為title字段創(chuàng)建的索引就是一個(gè)普通索引,MyIASM中默認(rèn)的BTREE類(lèi)型的索引,也是我們大多數(shù)情況下用到的索引。