MySQL單列索引和組合索引的區別介紹
MySQL單列索引是我們使用MySQL資料庫中經常會見到的,MySQL單列索引和組合索引的區別可能有很多人還不是十分的瞭解,下面就為您分析兩者的主要區別,供您參考學習。
為了形象地對比兩者,再建一個表:
CREATE TABLE myIndex ( i_testID INT NOT NULL AUTO_INCREMENT, vc_Name VARCHAR(50) NOT NULL,vc_City VARCHAR(50) NOT NULL, i_Age INT NOT NULL, i_SchoolID INT NOT NULL, PRIMARY KEY (i_testID) ); |
在這 10000 條記錄裡面 7 上 8 下地分佈了 5 條 vc_Name="erquan" 的記錄,只不過 city,age,school 的組合各不相同。
來看這條T-SQL:
SELECT i_testID FROM myIndex WHERE vc_Name='erquan' AND vc_City='鄭州' AND i_Age=25; |
首先考慮建MySQL單列索引:
在vc_Name列上建立了索引。執行 T-SQL 時,MYSQL 很快將目標鎖定在了vc_Name=erquan 的 5 條記錄上,取出來放到一中間結果集。在這個結果集裡,先排除掉 vc_City 不等於"鄭州"的記錄,再排除 i_Age 不等於 25 的記錄,最後篩選出唯一的符合條件的記錄。
雖然在 vc_Name 上建立了索引,查詢時MYSQL不用掃描整張表,效率有所提高,但離我們的要求還有一定的距離。同樣的,在 vc_City 和 i_Age 分別建立的MySQL單列索引的效率相似。
為了進一步榨取 MySQL 的效率,就要考慮建立組合索引。就是將 vc_Name,vc_City,i_Age 建到一個索引裡:
ALTER TABLE myIndex ADD INDEX name_city_age (vc_Name(10),vc_City,i_Age); |
建表時,vc_Name 長度為 50,這裡為什麼用 10 呢?因為一般情況下名字的長度不會超過 10,這樣會加速索引查詢速度,還會減少索引檔案的大小,提高 INSERT 的更新速度。
執行 T-SQL 時,MySQL 無須掃描任何記錄就到找到唯一的記錄。
肯定有人要問了,如果分別在 vc_Name,vc_City,i_Age 上建立單列索引,讓該表有 3 個單列索引,查詢時和上述的組合索引效率一樣嗎?大不一樣,遠遠低於我們的組合索引。雖然此時有了三個索引,但 MySQL 只能用到其中的那個它認為似乎是最有效率的單列索引。
建立這樣的組合索引,其實是相當於分別建立了
(vc_Name,vc_City,i_Age) ( vc_Name,vc_City ) ( vc_Name) |
這樣的三個組合索引!為什麼沒有 vc_City,i_Age 等這樣的組合索引呢?這是因為 mysql 組合索引“最左字首”的結果。簡單的理解就是只從最左面的開始組合。並不是只要包含這三列的查詢都會用到該組合索引,下面的幾個 T-SQL 會用到:
SELECT * FROM myIndex WHREE vc_Name="erquan" AND vc_City="鄭州" SELECT * FROM myIndex WHREE vc_Name="erquan" |
而下面幾個則不會用到:
SELECT * FROM myIndex WHREE i_Age=20 AND vc_City="鄭州" SELECT * FROM myIndex WHREE vc_City="鄭州" |
1. 為什麼使用索引
在無索引的情況下,MySQL會掃描整張表來查詢符合sql條件的記錄,其時間開銷與表中資料量呈正相關。對關係型資料表中的某些欄位建索引可以極大提高查詢速度(當然,不同欄位是否selective會導致這些欄位建立的索引對查詢速度的提升幅度不同,而且索引也並非越多越好,因為寫入或刪除時需要更新索引資訊)。對於MySQL的Innodb儲存引擎來說,大部分型別的index均以B-Tree資料結構的變種B+Tree來儲存(MEMORY型別的表還支援hash型別的索引)。B-Tree是資料庫或檔案系統中常用的一種資料結構,它是一種N叉平衡樹,這種樹結構保證了同層節點儲存的key有序,對於某個節點來說,其左子樹儲存的所有key均小於該節點儲存的key,其右子樹儲存的所有key均大於該節點儲存的key。此外,在工程實現上,還結合作業系統的區域性性原理做了很多優化,總之,b-tree的各種特性或優化技巧能保證:1) 查詢磁碟記錄時,讀盤次數最少;2) 任何insert和delete操作對樹結構的影響均很小;3) 樹本身的rebalance操作很高效。
2. MySQL使用索引的場景
MySQL在以下操作場景下會使用索引:1) 快速查詢符合where條件的記錄
2) 快速確定候選集。若where條件使用了多個索引欄位,則MySQL會優先使用能使候選記錄集規模最小的那個索引,以便儘快淘汰不符合條件的記錄。
3) 如果表中存在幾個欄位構成的聯合索引,則查詢記錄時,這個聯合索引的最左字首匹配欄位也會被自動作為索引來加速查詢。
例如,若為某表建立了3個欄位(c1, c2, c3)構成的聯合索引,則(c1), (c1, c2), (c1, c2, c3)均會作為索引,(c2, c3)就不會被作為索引,而(c1, c3)其實只利用到c1索引。
4) 多表做join操作時會使用索引(如果參與join的欄位在這些表中均建立了索引的話)
5) 若某欄位已建立索引,求該欄位的min()或max()時,MySQL會使用索引
6) 對建立了索引的欄位做sort或group操作時,MySQL會使用索引
3. 哪些SQL語句會真正利用索引
從MySQL官網文件"Comparison of B-Tree and Hash Indexes"可知,下面這些型別的SQL可能會真正用到索引:
1) B-Tree可被用於sql中對列做比較的表示式,如=, >, >=, <, <=及between操作
2) 若like語句的條件是不以萬用字元開頭的常量串,MySQL也會使用索引比如,SELECT * FROM tbl_name WHERE key_col LIKE 'Patrick%'或SELECT * FROM tbl_name WHERE key_col LIKE 'Pat%_ck%'可以利用索引,而SELECT * FROM tbl_name WHERE key_col LIKE '%Patrick%'(以萬用字元開頭)和SELECT * FROM tbl_name WHERE key_col LIKE other_col(like條件不是常量串)無法利用索引。
對於形如LIKE '%string%'的sql語句,若萬用字元後面的string長度大於3,則MySQL會利用Turbo Boyer-Moore algorithm演算法進行查詢。
3) 若已對名為col_name的列建了索引,則形如"col_name is null"的SQL會用到索引
4) 對於聯合索引,sql條件中的最左字首匹配欄位會用到索引,示例請參考本文第2節第3條對聯合索引的說明5) 若sql語句中的where條件不只1個條件,則MySQL會進行Index Merge優化來縮小候選集範圍
相關文章
- MySQL單列索引和組合索引的區別MySql索引
- mysql的組合索引MySql索引
- mysql組合索引,abc索引命中MySql索引
- MySQL的btree索引和hash索引的區別MySql索引
- MySQL索引介紹MySql索引
- MySQL Hash索引和B-Tree索引的區別MySql索引
- Mysql索引的使用-組合索引+跳躍條件MySql索引
- oracle複合索引介紹(多欄位索引)Oracle索引
- MySQL 組合索引不生效MySql索引
- sqlserver索引重建和索引重組的區別和操作方法SQLServer索引
- 聯合索引和多個單列索引使用中的索引命中情況及索引建立原則索引
- MySQL學習筆記:組合索引-索引下推MySql筆記索引
- MySQL組合索引和最左匹配原則MySql索引
- 認識SQLServer索引以及單列索引和多列索引的不同SQLServer索引
- 主鍵索引 (聚集索引) 和普通索引 (輔助索引) 的區別索引
- MySQL全面瓦解22:索引的介紹和原理分析MySql索引
- 簡單介紹MySQL索引失效的幾種情況MySql索引
- Mysql索引的使用 - 組合索引 + 範圍條件的處理MySql索引
- NULL在oracle和mysql索引上的區別NullOracleMySql索引
- ORACLE 索引和MYSQL INNODB 輔助索引對NULL的處理區別Oracle索引MySqlNull
- postgreSQL 索引(二)型別介紹SQL索引型別
- 索引與null(二):組合索引索引Null
- [轉]聚集索引和非聚集索引的區別索引
- 使用聚集索引和非聚集索引的區別索引
- mysql 字首索引 的一些介紹MySql索引
- mysql索引型別Normal,Unique,Full Text區別以及索引方法Btree,Hash的區別MySql索引型別ORM
- SQL Server 聚集索引和非聚集索引的區別SQLServer索引
- B樹索引和點陣圖索引的結構介紹索引
- Mysql innodb引擎和myisam引擎使用索引區別MySql索引
- 組合索引的前導列與查詢——ORACLE索引Oracle
- Sql索引介紹SQL索引
- MySQL的聯合索引MySql索引
- SQLT 最佳化SQL 用複合索引代替單列索引的案例SQL索引
- 索引與null(一):單列索引索引Null
- MYSQL中的普通索引,主健,唯一,全文索引區別MySql索引
- mysql 索引合併MySql索引
- MySQL複合索引MySql索引
- 【Mysql】InnoDB 中的聚簇索引、二級索引、聯合索引MySql索引