在innoDB中,有兩大索引類,分別是

讓客戶滿意是我們工作的目標,不斷超越客戶的期望值來自于我們對這個行業(yè)的熱愛。我們立志把好的技術(shù)通過有效、簡單的方式提供給客戶,將通過不懈努力成為客戶在信息化領(lǐng)域值得信任、有價值的長期合作伙伴,公司提供的服務(wù)項目有:國際域名空間、網(wǎng)絡(luò)空間、營銷軟件、網(wǎng)站建設(shè)、山陰網(wǎng)站維護、網(wǎng)站推廣。
執(zhí)行上述語句,執(zhí)行過程如下圖
從圖中,我們可以看出,掃了兩個索引樹
(1)先從普通索引name找到lisi
(2)再根據(jù)主鍵值9,再在聚集索引中找到行記錄。
這就是回表查詢,先在普通索引中找到主鍵值,再在聚集索引中找到行記錄。
很顯然,在一棵索引樹上就能獲取SQL所需的所有列數(shù)據(jù)的,就是索引覆蓋。
如下語句
很顯然,我們可以直接在name索引上直接找到id,name,不用再去回表。
而且我們通過explain的extra屬性也能觀察到
像我們開頭的SQL語句
我們只需要在name索引中再加個sex,name(name,sex),這樣變成了聯(lián)合索引,也是索引覆蓋。
顯示一個表所有索引的SQL語句是:
show index from 數(shù)據(jù)庫名.表名
查看某表某一列上的索引使用下面的SQL語句:
show index from 數(shù)據(jù)庫名.表名 where column_name like '列名'
下面的SQL語句在我的數(shù)據(jù)庫上執(zhí)行成功:
show index from web.clubuser where column_name like 'user'。
查看索引的語法格式如下:
SHOW INDEX FROM 表名 [ FROM 數(shù)據(jù)庫名]
語法說明如下:
表名:指定需要查看索引的數(shù)據(jù)表名。
數(shù)據(jù)庫名:指定需要查看索引的數(shù)據(jù)表所在的數(shù)據(jù)庫,可省略。比如,SHOW INDEX FROM student FROM test; 語句表示查看 test 數(shù)據(jù)庫中 student 數(shù)據(jù)表的索引。
示例
使用 SHOW INDEX 語句查看《MySQL創(chuàng)建索引》一節(jié)中 tb_stu_info2 數(shù)據(jù)表的索引信息,SQL 語句和運行結(jié)果如下所示。
mysql SHOW INDEX FROM tb_stu_info2\G
1. row
Table: tb_stu_info2
Non_unique: 0
Key_name: height
Seq_in_index: 1
Column_name: height
Collation: A
Cardinality: 0
Sub_part: NULL
Packed: NULL
Null: YES
Index_type: BTREE
Comment:
Index_comment:
1 row in set (0.03 sec)
其中各主要參數(shù)說明如下:
參數(shù) 說明
Table 表示創(chuàng)建索引的數(shù)據(jù)表名,這里是 tb_stu_info2 數(shù)據(jù)表。
Non_unique 表示該索引是否是唯一索引。若不是唯一索引,則該列的值為 1;若是唯一索引,則該列的值為 0。
Key_name 表示索引的名稱。
Seq_in_index 表示該列在索引中的位置,如果索引是單列的,則該列的值為 1;如果索引是組合索引,則該列的值為每列在索引定義中的順序。
Column_name 表示定義索引的列字段。
Collation 表示列以何種順序存儲在索引中。在 MySQL 中,升序顯示值“A”(升序),若顯示為 NULL,則表示無分類。
Cardinality 索引中唯一值數(shù)目的估計值。基數(shù)根據(jù)被存儲為整數(shù)的統(tǒng)計數(shù)據(jù)計數(shù),所以即使對于小型表,該值也沒有必要是精確的。基數(shù)越大,當進行聯(lián)合時,MySQL 使用該索引的機會就越大。
Sub_part 表示列中被編入索引的字符的數(shù)量。若列只是部分被編入索引,則該列的值為被編入索引的字符的數(shù)目;若整列被編入索引,則該列的值為 NULL。
Packed 指示關(guān)鍵字如何被壓縮。若沒有被壓縮,值為 NULL。
Null 用于顯示索引列中是否包含 NULL。若列含有 NULL,該列的值為 YES。若沒有,則該列的值為 NO。
Index_type 顯示索引使用的類型和方法(BTREE、FULLTEXT、HASH、RTREE)。
Comment 顯示評注。
首先說說索引的 優(yōu)點 :最大的好處無疑就是提高查詢效率。有的索引還能保證數(shù)據(jù)的唯一性,比如唯一索引。
而它的 壞處 也很明顯:索引也是文件,我們在創(chuàng)建索引時,也會創(chuàng)建額外的文件,所以會占用一些硬盤空間。其次,索引也需要維護,我們在增加刪除數(shù)據(jù)的時候,索引也需要去變化維護。當一個表的索引多了以后,資源消耗是很大的,所以必須結(jié)合實際業(yè)務(wù)再去確定給哪些列加索引。
再說說索引的基本結(jié)構(gòu)。一說到這里肯定會脫口而出:B+樹!了解B+樹前先要了解二叉查找樹和二叉平衡樹。 二叉查找樹 :左節(jié)點比父節(jié)點小,右節(jié)點比父節(jié)點大,所以二叉查找樹的中序遍歷就是樹的各個節(jié)點從小到大的排序。 二叉平衡樹 :左右子樹高度差不能大于1。B+樹就是結(jié)合了它們的特點,當然,不一定是二叉樹。
為什么要有二叉查找樹的特點?? 因為查找效率快,二分查找在這種結(jié)構(gòu)下,查找效率是很快的。 那為什么要有平衡樹的特點呢? 試想,如果不維護一顆樹的平衡性,當插入一些數(shù)據(jù)后,樹的形態(tài)有可能變得很極端,比如左子樹一個數(shù)據(jù)沒有,而全在右子樹上,這種情況下,二分查找和遍歷有什么區(qū)別呢?而就是因為這些特點需要去維護,所以就有了上面提到的缺點,當索引很多后,反而增加了系統(tǒng)的負擔。
接著說B+樹。 它的結(jié)構(gòu)如下 :
可以發(fā)現(xiàn),葉子節(jié)點其實是一個 雙向循環(huán)鏈表 ,這種結(jié)構(gòu)的好處就是,在范圍查詢的時候,我只用找到一個數(shù)據(jù),就可以直接返回剩余的數(shù)據(jù)了。比如找小于30的,只用找到30,其余的直接通過葉子節(jié)點間的指針就可以找到。再說說其他特點: 數(shù)據(jù)只存在于葉子節(jié)點 。當葉子節(jié)點滿了,如果再添加數(shù)據(jù),就會拆分葉子節(jié)點,父節(jié)點就多了個子節(jié)點。如果父節(jié)點的位置也滿了,就會擴充高度,就是拆分父節(jié)點,如25 50 75拆分成:25為左子樹,75為右子樹,50變成新的頭節(jié)點,此時B+樹的高度變成了3。它們的擴充的規(guī)律如下表,Leaf Page是葉子節(jié)點,index Page是非葉子節(jié)點。
再說說B樹 ,B樹相比較B+樹,它所有節(jié)點都存放數(shù)據(jù),所以在查找數(shù)據(jù)時,B樹有可能沒到達葉子節(jié)點就結(jié)束了。再者,B樹的葉子節(jié)點間不存在指針。
最后說說Hash索引 ,相較于B+樹,Hash索引最大的優(yōu)點就是查找數(shù)據(jù)快。但是Hash索引最大的問題就是不支持范圍查詢。試想,如果查詢小于30的數(shù)據(jù),hash函數(shù)是根據(jù)數(shù)據(jù)的值找到其對應(yīng)的位置,誰又知道小于30的有哪幾個數(shù)據(jù)。而B+樹正好相反,范圍查詢是它的強項。
附錄: Hash到底是啥?? 哈希中文名散列,哈希只是它的音譯。 為啥都說Hash快?? 首先有一塊哈希表(散列表),它的數(shù)據(jù)結(jié)構(gòu)是個數(shù)組,一個任意長度的數(shù)據(jù)通過hash函數(shù)都可以變成一個固定長度的數(shù)據(jù),叫hash值。然后通過hash值確定在數(shù)組中的位置,相同數(shù)據(jù)的hash值是相同的,所以我們存儲一個數(shù)據(jù)以后,只需O(1)的時間復(fù)雜度就可以找到數(shù)據(jù)。 那hash函數(shù)又是啥?? 算術(shù)運算或位運算,很多應(yīng)用里都有hash函數(shù),但實際運算過程大不一樣。這是Java里String的hashCode方法:
publicint hashCode() {
}
還有一個問題,hash函數(shù)計算出來的hash值有可能存在碰撞,即兩個不同的數(shù)據(jù)可能存在相同的hash值,在MySQL或其他的應(yīng)用中,如Java的HashMap等,如果存在碰撞就會以當前數(shù)組位置為頭節(jié)點,轉(zhuǎn)變成一個鏈表。
說到這里也清楚了為啥Java中引用類型要同時重寫hashCode和equals了。兩個對象,實例就算一模一樣,它們的hash值也不相等, 為啥不相等?? 默認的Object的hashCode方法會根據(jù)對象來計算hash值的,實例相同,但它們還是兩個不同的對象啊,所以我們重寫hashCode時,最簡單的方法就是調(diào)用Object的hashCode方法,然后傳入該引用類型的屬性,讓hashCode方法只根據(jù)這幾個屬性來計算,那么實例相同的話,它們的hash值也會相等。等hashCode比較完后,如果相等再比較實例內(nèi)容,也就是equals,確保不是hash碰撞。
索引的分類
如果我們指定了一個主鍵,那么這個主鍵就是主鍵索引。如果我們沒有指定,Mysql就會自動找一個非空的唯一索引當主鍵。如果沒有這種字段,Mysql就會創(chuàng)建一個大小為6字節(jié)的自增主鍵。如果有多個非空的唯一索引,那么就讓第一個定義為唯一索引的字段當主鍵,注意,是第一個定義,而不是建表時出現(xiàn)在前面的。
對于輔助索引來說,它們的B+樹結(jié)構(gòu)稍微有點特殊,它們的葉子節(jié)點存儲的是主鍵,而不是整個數(shù)據(jù)。所以在大部分情況下,使用輔助索引查找數(shù)據(jù),需要二次查找。但并不是所有情況都需要二次查找。比如查找的數(shù)據(jù)正好就是當前索引字段的值,那么直接返回就行。這里提一句,B+樹的key就是對應(yīng)索引字段的內(nèi)容。
而輔助索引又有一些分類:唯一索引:不能出現(xiàn)重復(fù)的值,也算一種約束。普通索引:可以重復(fù)、可以為空,一般就是查詢時用到。前綴索引:只適用于字符串類型數(shù)據(jù),對字符串前幾個字符創(chuàng)建索引。全文索引:作用是檢測大文本數(shù)據(jù)中某個關(guān)鍵字,這也是搜索引擎的一種技術(shù)。
注意,聚集索引、非聚集索引和前面幾個索引的分類并不是一個層面上的。上面的幾個分類是從索引的作用來分析的。聚集、非聚集索引是從索引文件上區(qū)分的。主鍵索引就屬于聚集索引,即索引和數(shù)據(jù)存放在一起,葉子節(jié)點存放的就是數(shù)據(jù)。數(shù)據(jù)表的.idb文件就是存放該表的索引和數(shù)據(jù)。
輔助索引屬于非聚集索引,說到這也就明白了。索引和數(shù)據(jù)不存放在一起的就是非聚集索引。在MYISAM引擎中,數(shù)據(jù)表的.MYI文件包含了表的索引, 該表的 葉子節(jié)點存儲索引和索引對應(yīng)數(shù)據(jù)的指針,指向.MYD文件的數(shù)據(jù)。
索引的幾點使用經(jīng)驗
經(jīng)常被查詢的字段;經(jīng)常作為條件查詢的字段;經(jīng)常用于外鍵連接或普通的連表查詢時進行相等比較字段;不為null的字段;如果是多條件查詢,最好創(chuàng)建聯(lián)合索引,因為聯(lián)合索引只有一個索引文件。
經(jīng)常被更新的字段、不經(jīng)常被查詢的字段、存在相同功能的字段
查看索引
mysql show index from tblname;
mysql show keys from tblname;
· Table
表的名稱。
· Non_unique
如果索引不能包括重復(fù)詞,則為0。如果可以,則為1。
· Key_name
索引的名稱。
· Seq_in_index
索引中的列序列號,從1開始。
· Column_name
列名稱。
· Collation
列以什么方式存儲在索引中。在MySQL中,有值‘A’(升序)或NULL(無分類)。
· Cardinality
索引中唯一值的數(shù)目的估計值。通過運行ANALYZE TABLE或myisamchk -a可以更新。基數(shù)根據(jù)被存儲為整數(shù)的統(tǒng)計數(shù)據(jù)來計數(shù),所以即使對于小型表,該值也沒有必要是精確的。基數(shù)越大,當進行聯(lián)合時,MySQL使用該索引的機 會就越大。
· Sub_part
如果列只是被部分地編入索引,則為被編入索引的字符的數(shù)目。如果整列被編入索引,則為NULL。
· Packed
指示關(guān)鍵字如何被壓縮。如果沒有被壓縮,則為NULL。
· Null
如果列含有NULL,則含有YES。如果沒有,則該列含有NO。
· Index_type
用過的索引方法(BTREE, FULLTEXT, HASH, RTREE)。
· Comment
mysql 添加索引后 在查詢的時候是mysql就自動從索引里面查詢了。如果需要也可以單獨根據(jù)索引查詢,這個看使用場景
MYSQL在創(chuàng)建索引后對索引的使用方式分為兩種:
1 由數(shù)據(jù)庫的查詢優(yōu)化器自動判斷是否使用索引;
2 用戶可在寫SQL語句時強制使用索引
本文標題:mysql索引怎么查數(shù)據(jù) mysql如何使用索引查詢
文章源于:http://chinadenli.net/article10/hgpcgo.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供服務(wù)器托管、網(wǎng)站維護、電子商務(wù)、網(wǎng)站收錄、網(wǎng)站營銷、網(wǎng)站策劃
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)