索引關鍵字的選取原則

索引關鍵字的選取原則

轉自
作者總結的很好

http://blog.itpub.net/29272216/viewspace-1243730/

1、 表的某個字段值得離散度越高,該字段越適合選作索引的關鍵字。主鍵字段以及唯一性約束字段適合選作索引的關鍵字,原因就是這些字段的值非常離散。尤其是在主鍵字段創建索引時,cardinality(基數,集的勢)的值就等於該表的行數。MySQL在處理主鍵約束以及唯一性約束時,考慮周全。數據庫用戶創建主鍵約束的同時,MySQL自動創建主索引(primary index),且索引名稱爲Primary;數據庫用戶創建唯一性索引時,MySQL自動創建唯一性索引(unique index),默認情況下,索引名爲唯一性索引的字段名。
2、 佔用存儲空間少的字段更適合選作索引的關鍵字。例如,與字符串相比,整數字段佔用的存儲空間較少,因此,較爲適合選作索引關鍵字。
3、 存儲空間固定的字段更適合選作索引的關鍵字。與text類型的字段相比,char類型的字段較爲適合選作索引關鍵字。
4、 Where子句中經常使用的字段應該創建索引,分組字段或者排序字段應該創建索引,兩個表的連接字段應該創建索引。
5、 更新頻繁的字段不適合創建索引,不會出現在where子句中的字段不應該創建索引。
6、 最左前綴原則。
7、 儘量使用前綴索引。
引入索引的目的就是提高數據的檢查效率,因此索引關鍵字的選擇與select語句息息相關。這句話有兩個含義:一是,select語句的設計可以決定索引的設計;索引的設計也同樣影響着select語句的設計。例如原則1與原則2,可以影響select語句的設計;而select語句中的where子句、group by子句以及,又可以影響索引的設計。兩個表的連接字段應該創建索引,外鍵約束一經創建,MySQL會自動地創建與外鍵相對應的索引,這是由於外鍵字段通常是兩個表的連接字段。
複合索引還有一個優點,它通過被稱爲“最左前綴”(leftmost prefixing)的概念體現出來的。假設向一個表的多個字段(例如fristname、lastname、address)創建複合索引(索引名爲fname_lname_address).當where查詢條件是以下各種字段的組合是,MySQL將使用fname_lname_address索引。其他情況將無法使用fname_lname_address索引。可以理解:一個複合索引(firstname、lastname、address)等效於(firstname,llastname,age)、(firstname,lastname)以及(firstname)三個索引。基於最做前綴原則,應儘量避免創建重複的索引,例如,創建了fname_lname_address索引後,就無需再first_name子段上單獨創建一個索引。

如果數據庫表的存儲引擎是MyISAM,那麼創建主鍵的約束的同時,MySQL會自動創建主鍵索引。如果數據庫表的存儲引擎是InnoDB,那麼創建主鍵約束的同時,MySQL會自動創建聚簇索引。
MySQL還支持全文索引(fulltext),當查詢數據量大的字符串信息時,使用全文索引可以大幅提升字符串的檢索效率。需要注意的是,全文索引只能創建在char、varchar或者text字符串類型的字段上,且全文索引不支持前綴索引。


以下引用這個作者也是引用的都是沒說地址
(http://blog.csdn.net/z69183787/article/details/46731765)


索引建立的原則
用於索引的最好的備選數據列是那些出現在WHERE子句、join子句、ORDER BY或GROUP BY子句中的列。
僅僅出現在SELECT關鍵字後面的輸出數據列列表中的數據列不是很好的備選列

SELECT
col_a <- 不是備選列
FROM
tbl1 LEFT JOIN tbl2
ON tbl1.col_b = tbl2.col_c <- 備選列
WHERE
col_d = expr; <- 備選列

當然,顯示的數據列與WHERE子句中使用的數據列也可能相同。
我們的觀點是輸出列表中的數據列本質上不是用於索引的很好的備選列。

  1. 複合索引的建立以及最左前綴原則
    索引字符串值的前綴(prefixe)。如果你需要索引一個字符串數據列,那麼最好在任何適當的情況下都應該指定前綴長度。
    例如,如果有CHAR(200)數據列,如果前面10個或20個字符都不同,就不要索引整個數據列。
    索引前面10個或20個字符會節省大量的空間
    你可以索引CHAR、VARCHAR、BINARY、VARBINARY、BLOB和TEXT數據列的前綴。

假設你在表的state、city和zip數據列上建立了複合索引。索引中的數據行按照state/city/zip次序排列,
因此它們也會自動地按照state/city和state次序排列。這意味着,即使你在查詢中只指定了state值,
或者指定state和city值,MySQL也可以使用這個索引。因此,這個索引可以被用於搜索如下所示的數據列組合:
state, city, zip
state, city
state

MySQL不能利用這個索引來搜索沒有包含在最左前綴的內容。例如,如果你按照city或zip來搜索,
就不會使用到這個索引。如果你搜索給定的state和具體的ZIP代碼(索引的1和3列),
該索引也是不能用於這種組合值的,儘管MySQL可以利用索引來查找匹配的state從而縮小搜索的範圍。

如果你考慮給已經索引過的表添加索引,那麼就要考慮你將增加的索引是否是已有的多列索引的最左前綴。
如果是這樣的,不用增加索引,因爲已經有了(例如,如果你在state、city和zip上建立了索引,那麼沒有必要再增加state的索引)。

  1. 實例分析
    通過實例理解單列索引、多列索引以及最左前綴原則
    實例:現在我們想查出滿足以下條件的用戶id:
    mysql>SELECT `uid` FROM people WHERE lname`=’Liu’ AND `fname`=’Zhiqun’ AND `age`=26
    因爲我們不想掃描整表,故考慮用索引。

單列索引:
ALTER TABLE people ADD INDEX lname (lname);
將lname列建索引,這樣就把範圍限制在lname=’Liu’的結果集1上,之後掃描結果集1,產生滿足fname=’Zhiqun’的結果集2,再掃描結果集2,找到 age=26的結果集3,即最終結果。

由於建立了lname列的索引,與執行表的完全掃描相比,效率提高了很多,但我們要求掃描的記錄數量仍舊遠遠超過了實際所需 要的。雖然我們可以刪除lname列上的索引,再創建fname或者age 列的索引,但是,不論在哪個列上創建索引搜索效率仍舊相似。

多列索引:
ALTER TABLE people ADD INDEX lname_fname_age (lame,fname,age);
爲了提高搜索效率,我們需要考慮運用多列索引,由於索引文件以B-Tree格式保存,所以我們不用掃描任何記錄,即可得到最終結果。

注:在mysql中執行查詢時,只能使用一個索引,如果我們在lname,fname,age上分別建索引,執行查詢時,只能使用一個索引,mysql會選擇一個最嚴格(獲得結果集記錄數最少)的索引。

3.最左前綴:顧名思義,就是最左優先,上例中我們創建了lname_fname_age多列索引,相當於創建了(lname)單列索引,(lname,fname)組合索引以及(lname,fname,age)組合索引。

注:在創建多列索引時,要根據業務需求,where子句中使用最頻繁的一列放在最左邊。

發佈了29 篇原創文章 · 獲贊 12 · 訪問量 7萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章