Mysql官方對索引的定義是:索引(Index)是幫助Mysql高效獲取數(shù)據(jù)的數(shù)據(jù)結(jié)構(gòu)价捧。
可以得到索引的本質(zhì):索引是一種數(shù)據(jù)結(jié)構(gòu)策州。
為什么要建索引吃嘿?
索引的目的在于提高查詢效率。
比如:如果要查“mysql”這個單詞币叹,我們肯定需要定位到m字母姨拥,然后從下往下找到y(tǒng)字母绅喉,再找到剩下的sql。
如果沒有索引叫乌,那么你可能需要a----z柴罐,會使查找效率變慢。
索引也可以理解為:排好序的快速查找數(shù)據(jù)結(jié)構(gòu)憨奸。
索引有兩大功能:查找快革屠,排好序。也即建的索引將會影響到Sql的兩部分排宰。
第一部分:就是where條件后面這部分的條件約束是否用到索引似芝,這部分就是負責(zé)查找的條件過濾。
第二部分:索引會影響到where后面的查找以及order by后面的排序板甘。
在數(shù)據(jù)本身之外党瓮,數(shù)據(jù)庫系統(tǒng)還維護著滿足特定查找算法的數(shù)據(jù)結(jié)構(gòu),這些數(shù)據(jù)結(jié)構(gòu)以某種方式引用(指向)數(shù)據(jù)盐类,這樣就可以在這些數(shù)據(jù)結(jié)構(gòu)上實現(xiàn)高級查找算法寞奸。這種數(shù)據(jù)結(jié)構(gòu),就是索引在跳。下圖就是一種可能的索引方式示例:
索引的優(yōu)勢:
類似大學(xué)圖書館中建書目的索引,提高數(shù)據(jù)檢索的效率韭脊,降低了數(shù)據(jù)庫的IO成本童谒。
通過對索引列對數(shù)據(jù)進行排序,降低數(shù)據(jù)排序的成本沪羔,降低了CPU的消耗饥伊。
索引的劣勢:
實際上索引也是一張表,該表保存了主鍵與索引的字段蔫饰,并指向?qū)嶓w表的記錄琅豆,所以索引列也是要占用空間的。
雖然索引大大的提高了查詢的效率篓吁,同時卻會降低更新表的速度茫因,如對表進行inser,update以及detele。因為更新表時杖剪,Mysql不僅要保存數(shù)據(jù)冻押,還要保存一下索引文件每次更新添加了索引列的字段,都會調(diào)整因為更新所帶來的鍵值變化后的索引信息盛嘿。
索引只是提高查詢效率的一個因素洛巢,如果有大數(shù)據(jù)量的表,就需要花時間研究建立最優(yōu)秀的索引或優(yōu)化查詢語句次兆。
索引分類和建索引語句:
1.單值索引:即一個索引只包含單個列稿茉,一個表可以有多個單列索引。
2.唯一索引:索引列的值必須唯一芥炭,但允許有空值狈邑。
3.復(fù)合索引:即一個索包含多個列。
基本的語句:
如果建的是唯一索引蚤认,那么就加UNIQUE這個關(guān)鍵字米苹,不加就可以省略。
如果是CHAR VARCHAR類型砰琢,length可以小于字段的實際長度蘸嘶。如果是BLOB和TEXT類型,必須指定length陪汽。
如果columnname(length)寫了多個训唱,那么就是復(fù)合索引。
第一種建法:
1.CREATE [UNIQUE] INDEX indexName ON mytable(columnname(length));//單值索引?
2.ALTER mytable ADD [UNIQUE] INDEX [indexName] ON (columnname(length))? //單值索引
刪除索引:
3.DROP INDEX [indexName]ON mytable;? //意思就是把某個表中的某個索引給刪了
查看索引:
4.SHOW INDEX FROM Table_name\G;
有四種方式來添加數(shù)據(jù)表的索引:
1.ALTER TABLE tbl_name ADD PRIMARY KEY (column_list): 該語句添加一個主鍵挚冤,這意味著索引值必須是唯一的况增,且不能為NULL。
2.ALTER TABLE tbl_name ADD UNIQUE index_name (column_list): 這條語句創(chuàng)建索引的值必須是唯一的(除了NULL外训挡,NULL可能會出現(xiàn)多次)澳骤。
3.ALTER TABLE tbl_name ADD INDEX index_name (column_list): 添加普通索引歧强,索引值可出現(xiàn)多次。
4.ALTER TABLE tbl_name ADD FULLTEXT index_name (column_list):該語句指定了索引為 FULLTEXT 为肮,用于全文索引摊册。
Java開發(fā)相關(guān)的Mysql索引結(jié)構(gòu):
BTree索引:
【初始化介紹】 一顆b+樹,淺藍色的塊我們稱之為一個磁盤塊颊艳,可以看到每個磁盤塊包含幾個數(shù)據(jù)項(深藍色所示)和指針(黃色所示)茅特,如磁盤塊1包含數(shù)據(jù)項17和35,包含指針P1棋枕、P2白修、P3,P1表示小于17的磁盤塊重斑,P2表示在17和35之間的磁盤塊熬荆,P3表示大于35的磁盤塊。真實的數(shù)據(jù)存在于葉子節(jié)點即3绸狐、5卤恳、9、10寒矿、13突琳、15、28符相、29拆融、36、60啊终、75镜豹、79、90蓝牲、99趟脂。非葉子節(jié)點只不存儲真實的數(shù)據(jù),只存儲指引搜索方向的數(shù)據(jù)項例衍,如17昔期、35并不真實存在于數(shù)據(jù)表中。
【查找過程】如果要查找數(shù)據(jù)項29佛玄,那么首先會把磁盤塊1由磁盤加載到內(nèi)存硼一,此時發(fā)生一次IO,在內(nèi)存中用二分查找確定29在17和35之間梦抢,鎖定磁盤塊1的P2指針般贼,內(nèi)存時間因為非常短(相比磁盤的IO)可以忽略不計,通過磁盤塊1的P2指針的磁盤地址把磁盤塊3由磁盤加載到內(nèi)存,發(fā)生第二次IO哼蛆,29在26和30之間蕊梧,鎖定磁盤塊3的P2指針,通過指針加載磁盤塊8到內(nèi)存人芽,發(fā)生第三次IO,同時內(nèi)存中做二分查找找到29绩脆,結(jié)束查詢萤厅,總計三次IO。
真實的情況是靴迫,3層的b+樹可以表示上百萬的數(shù)據(jù)惕味,如果上百萬的數(shù)據(jù)查找只需要三次IO,性能提高將是巨大的玉锌,如果沒有索引名挥,每個數(shù)據(jù)項都要發(fā)生一次IO,那么總共需要百萬次的IO主守,顯然成本非常非常高禀倔。
以下索引了解即可。
Hash索引
full-text全文索引
R-Tree索引
哪些情況下適合建索引参淫?
1.主鍵自動建立唯一索引救湖。
2.頻繁作為查詢條件的字段應(yīng)該建索引。
3.查詢中與其他表關(guān)聯(lián)的字段涎才,外鍵關(guān)系建立索引鞋既。
4.頻繁更新的字段不適合創(chuàng)建索引:因為每次更新不單單只是更新了記錄,還會更新索引耍铜,加重了IO負擔(dān)邑闺。
5.Where條件里用不到的字段不創(chuàng)建索引。
6.單鍵/組合索引的選擇問題(高并發(fā)下傾向創(chuàng)建組合索引)棕兼。
7.查詢中排序的字段陡舅,排序字段若通過索引去訪問將大大提高排序速度。
8.查詢中統(tǒng)計或者分組字段伴挚。
哪些情況下不適合建索引蹭沛?
1.表記錄太少。
2.經(jīng)常增刪改的表:提高了查詢效率章鲤,但是同時卻會降低了更新表的速度摊灭,如對表進行INSERT,UPDATE以及DELETE。因為更新表時败徊,MySql不僅要保存數(shù)據(jù)帚呼,還要保存索引文件。
3.數(shù)據(jù)重復(fù)并且分布平均的表字段,因此應(yīng)該只給最經(jīng)常查詢和最經(jīng)常排序的數(shù)據(jù)列建立索引煤杀,但如果某個數(shù)據(jù)列包含許多重復(fù)的內(nèi)容眷蜈,為它建立索引就沒有太大的實際效果。