全值匹配:指的是和索引中所有的列進行匹配,如可以找到姓名為:Cuba(名) Allen(姓) 、生於1988-10-04的人,如where lastname=‘Allen’ and firstname=‘Cuba’ and born="1988-10-04"匹配最左字首:可以查詢姓為Allen的人,如where lastname=‘Allen’匹配列字首:也可以匹配某一列的值的開頭部分,如where lastname like ‘A%’ 或者where firstname like ‘M%’匹配範圍:可以匹配姓在Allen和Bill之間的人精確匹配某一列並匹配另外一列:查詢所有姓為Allen、並且名字是以M開頭的人,如where lastname=‘Allen’ and firstname like ‘M%’訪問索引資料:這種查詢只需要訪問索引本身就行了,不需要訪問資料行,也就是常說的索引覆蓋,舉個例子:如果只需要找到姓為Allen的人的名稱, 而不需要這個人其他的資訊,名稱就存在與索引中,不需要再去資料行中查詢資料了。
雜湊索引:基於雜湊表來實現的索引型別,如果存在雜湊衝突,索引會使用連結串列來存放多個記錄到一個雜湊桶中。舉個例子:如果存在以下索引 key USING HASH(firstname),雜湊索引會使用雜湊函式計算出firstname列的雜湊值作為key,並將行指標作為value儲存,當使用 =、IN()、<=>操作時,先計算出sql語句操作查詢值的雜湊值,並使用其來查詢雜湊表對應的行指標,從而返回資料。
什麼是索引?
索引是資料庫快速找到記錄行的一種資料結構,類似我們看書時的目錄,它是良好效能的關鍵因素。尤其是表中的資料量越來越大時,如果索引使用不當,會嚴重影響效能。索引也是最常見的資料庫最佳化手段,它能輕易的將查詢效能提高好幾個量級。
MySQL索引型別?mysql索引資料是儲存在儲存引擎中的,所以不同儲存引擎中索引的工作方式並不一樣。
B-Tree索引:基於B+樹(一種多叉搜尋數樹)來實現的索引型別,一般也是使用的最多的索引型別,之所以選擇B+樹而不是其他資料結構,是因為B+樹在查詢時間複雜度可以維持在O(logn)的級別上,由於B+的矮胖(從根節點到葉子節點的距離可以維持在較小範圍)特性減少磁碟IO次數、資料只存在葉子節點中並且按順序儲存也可以支援快速的範圍查詢,這是其他結構無法滿足的!
B+索引中值是按順序儲存的,葉子節點到根節點的距離都相同,從B+樹的根節點開始往下查詢,節點儲存了指向葉子節點的指標,透過將要查詢的值和每個節點值比較後,一層層定位到最終的葉子結點上,葉子節點儲存的就是行資料、指標或主鍵。
假如我們索引列是:
key(lastname(姓),firstname(名),born),可以使用B+樹索引的查詢型別包括:全鍵值、鍵值範圍、鍵字首查詢,其中鍵字首只適用於最左字首查詢:
全值匹配:指的是和索引中所有的列進行匹配,如可以找到姓名為:Cuba(名) Allen(姓) 、生於1988-10-04的人,如where lastname=‘Allen’ and firstname=‘Cuba’ and born="1988-10-04"匹配最左字首:可以查詢姓為Allen的人,如where lastname=‘Allen’匹配列字首:也可以匹配某一列的值的開頭部分,如where lastname like ‘A%’ 或者where firstname like ‘M%’匹配範圍:可以匹配姓在Allen和Bill之間的人精確匹配某一列並匹配另外一列:查詢所有姓為Allen、並且名字是以M開頭的人,如where lastname=‘Allen’ and firstname like ‘M%’訪問索引資料:這種查詢只需要訪問索引本身就行了,不需要訪問資料行,也就是常說的索引覆蓋,舉個例子:如果只需要找到姓為Allen的人的名稱, 而不需要這個人其他的資訊,名稱就存在與索引中,不需要再去資料行中查詢資料了。這裡需要注意的是葉子節點存什麼型別資料不同的儲存引擎還不一樣,在MyISAM中葉子節點儲存的是資料物理位置(指標),而InnoDB使用B+結構儲存的是原始資料或主鍵,也就是我們常說的聚簇索引,它儲存的是原始全量資料、鍵值,聚簇索引指的是一種資料索引組織形式,它將資料和索引聚集在一起所以叫聚簇,它本身並不是一種索引型別。
一般InnoDB查詢過程為從輔助索引上開始查詢到資料主鍵,然後在主鍵索引中用主鍵再次查詢,最後再找到資料,雖然多了一次查詢過程,但更新資料不會導致聚簇索引頻繁變化。而在MyISAM中不需要2次索引查詢,因為葉子節點儲存的是資料的物理地址可以直接定位,雖然查詢看似簡單了,但是物理地址會因為資料頻繁變更而發生變化。
假設有以下資料:
InnoDB(聚簇索引)資料查詢過程:
MyISAM(非聚簇索引結構)資料查詢過程:
雜湊索引:基於雜湊表來實現的索引型別,如果存在雜湊衝突,索引會使用連結串列來存放多個記錄到一個雜湊桶中。舉個例子:如果存在以下索引 key USING HASH(firstname),雜湊索引會使用雜湊函式計算出firstname列的雜湊值作為key,並將行指標作為value儲存,當使用 =、IN()、<=>操作時,先計算出sql語句操作查詢值的雜湊值,並使用其來查詢雜湊表對應的行指標,從而返回資料。
這裡需要注意是:
雜湊索引只儲存雜湊值和行指標,索引索引本身沒有行資料,也就沒有所謂的索引覆蓋。雜湊索引沒有按雜湊值的順序排列,所有不支援排序操作。不支援部分索引列的匹配,雜湊索引使用你指定的全部列來計算雜湊值,列入(A,B)如果查詢只有列A,則索引無發匹配。雜湊索引只支援等值比較(=、in(),<=>)。雜湊衝突較高時,查詢效率就變成了連結串列,複雜度從O(1)變為O(n)。空間資料索引:MyISAM支援空間索引可以用來儲存地理資料。必須使用GIS相關函式如MBRCONUNTAINS()來維護資料,因為本身mysql對GIS的支援下不完善,這中特性使用很少。
全文索引:這是一種特殊型別的索引,他查詢的是索引列中文字的關鍵詞,而不是比較索引值,全文索引的使用要注意列的文字大小和資料量,它的匹配方式類似於搜尋引擎。
索引的優缺點?大大減少了伺服器掃描表的資料量。避免不必要的排序和臨時表。將隨機IO變為順序IO。對於非常小的表,全表掃描可能比索引更快,對於中型資料量表,索引將會非常有效,對於TB級別的表來說,索引的維護和效果可能沒有我們想象的那樣好,這是可以使用表分割槽、業務拆分表和分庫等技術。常見的索引最佳化方式及注意事項?不要把索引的列納入表示式,也不能是函式引數,如where aid+1=5、where to_days(col)<=10.選擇重複性較低的列建索引,重複性較高會導致索引失效,全表掃描。多列索引中很多常見的錯誤是,喜歡為每個列建立獨立索引,實際上這是錯誤的!要選擇合適的順序和列來合併索引,來看個簡單例子:表資料為:
分別建2個獨立索引:inx_name, inx_company :
現在執行以下語句:
SELECT * from tuser where `name`="22" or company="bb"
結果顯示並沒有使用索引來查詢資料:
現在加一個多列索引:inx_name_company
執行同樣的sql顯示使用了多列索引:
不要在大文字欄位建全量索引,這會然導致索引資料較大,查詢較慢,可以建一個字首索引,例如//在city列上取前7個字元作為索引 mysql > alter table demo add key(city(7))
這是一種使索引更小,更快的方法,但缺點是無法使用綴索引order by或group by