Mysql高級之索引優(yōu)化(三)

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條件后面這部分的條件約束是否用到索引,這部分就是負責查找的條件過濾。

第二部分:索引會影響到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),就是索引。下圖就是一種可能的索引方式示例:

左邊是數(shù)據(jù)表,一共有兩列七條記錄,最左邊的是數(shù)據(jù)記錄的物理地址 為了加快Col2的查找,可以維護一個右邊所示的二叉查找樹,每個節(jié)點分別包含索引鍵值和一個指向?qū)?yīng)數(shù)據(jù)記錄物理地址的指針,這樣就可以運用二叉查找在一定的復(fù)雜度內(nèi)獲取到相應(yīng)數(shù)據(jù),從而快速的檢索出符合條件的記錄。

索引的優(yōu)勢:

類似大學圖書館中建書目的索引,提高數(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負擔。

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)容,為它建立索引就沒有太大的實際效果。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容