mysql單列索引 多列索引的使用

2021-08-15 11:01:36 字數 2624 閱讀 6022

資料庫的索引可以加快查詢速度,原因是索引使用特定的資料結構(b-tree)對特定的列額外組織存放,加快儲存引擎(索引是儲存引擎實現)查詢記錄的速度。

索引優化是資料庫優化的最重要手段。

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

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

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

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

MySQL單列索引和多列索引

在設計mysql表索引的時候,可能有個問題,就是多個單列索引好,還是設計為多列索引好 下面從不同角度分析下這個問題 1.多個單列索引 定義 即是在表中在需要索引的字段上為每個字段設計乙個索引 特點 簡單,索引個數多 2.多列索引 定義 即是在表中根據查詢需求在多個欄位上設計乙個索引 特點 稍微複雜,...

mysql 單列索引與多列索引

以下的文章主要介紹的是mysql資料庫索引型別,其中包括普通索引,唯一索引,主鍵索引與主鍵索引,以及對這些索引的實際應用或是建立有乙個詳細介紹,以下就是文章的主要內容描述。1 普通索引 這是最基本的mysql資料庫索引,它沒有任何限制。它有以下幾種建立方式 建立索引 create index ind...

MySQL使用單列索引和多列索引

討論mysql選擇索引時單列單列索引和多列索引使用,以及多列索引的最左字首原則。1.單列索引 在效能優化過程中,選擇在哪些列上建立索引是最重要的步驟之一。可以考慮使用索引的主要有兩種型別的列 在where子句中出現的列,在join子句中出現的列。請看下面這個查詢 select age 不使用索引 f...