數據庫索引- 復合索引(多列索引)


對復合索引,按照字段在查詢條件中出現的頻度建立索引。在復合索引中,記錄首先按照第一個字段排序。對於在第一個字段上取值相同的記錄,系統再按照第二個字段的取值排序,以此類推。因此只有復合索引的第一個字段出現在查詢條件中,該索引才可能被使用,因此將應用頻度高的字段,放置在復合索引的前面,會使系統最大可能地使用此索引,發揮索引的作用。

二、多列索引適合的場景

       1.全字段匹配

       2.匹配部分最左前綴

       3.匹配第一列

       4.匹配第一列范圍查詢(可用用like a%,但不能使用like %b)

       5.精確匹配某一列和和范圍匹配另外一列

       order by操作中出現的字段同樣適用於按值查找的規則,where+order by中出現的字段需可以建立滿足如上五種規則多列索引。使用多列所需需要按照最左索引列查找;不能跳過中間列;如果某一列是范圍查詢,那么其右邊所有列無法使用索引。IN什么情況下是范圍查詢,什么情況下是多個等值查詢?如果有order by排序時,多個等於條件查詢就是范圍查詢,沒有order by排序就沒有限制。

       例如,建立多列索引(name, age, id),只能使用索引的前兩列。in是范圍查詢
... where name='nginx.cn' and age in(15,16,17) order by id

       可以使用整個索引,in是按值查詢
... where name='nginx.cn' and age in(15,16,17) and id ='3'

三、復合索引的建立以及最左前綴原則

      索引字符串值的前綴(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的索引)。

四、通過實例理解單例索引、多列索引以及最左前綴原則

      實例:現在我們想查出滿足以下條件的用戶id:
      mysql>SELECT `uid` FROM people WHERE lname`='Liu'  AND `fname`='Zhiqun' AND `age`=26 ; 因為我們不想掃描整表,故考慮用索引。

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

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

     2、多列索引:
     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子句中使用最頻繁的一列放在最左邊。

 

一、簡介     

       數據庫的索引可以加快查詢速度,原因是索引使用特定的數據結構(B-Tree)對特定的列額外組織存放,加快存儲引擎(索引是存儲引擎實現)查找記錄的速度。
       索引優化是數據庫優化的最重要手段。

       如果查詢語句使用索引(通常是where條件匹配索引)就會利用樹的結構加快查找,索引會按值查找到要查找的行在表中位置,不需回表查詢數據的就是聚簇索引(索引和數據存放在一起)。通常是需要回表再查數據,需要消耗額外的磁盤IO。所以有些時候(如按順序讀取數據)全表掃描會比使用索引快的原因就在於此。

       查詢條件只有一個字段時,在該字段建立索引即可,可優化的地方是對於text blob字段使用前綴索引。

       當查詢條件有多個字段時,單列索引和多列索引有很大的區別。如果使用多列索引,where條件中字段的順序非常重要,需要滿足最左前綴列。最左前綴:查詢條件中的所有字段需要從左邊起按順序出現在多列索引中,查詢條件的字段數要小於等於多列索引的字段數,中間字段不能存在范圍查詢的字段(<,like等),這樣的sql可以使用該多列索引。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM