比如郵箱登陸的系統,有一張表:
mysql> create table suser(
id bigint unsigned primary key,
email varchar(64),
...
)engine=innodb;
有一條sql語句:
mysql>
select f1, f2 from suser where email=
'***'
;
不在email加索引的話,就會進行全盤掃瞄,效率比較低。
mysql 是支援字首索引的,有兩種加索引的方式:
mysql> alter table suser add index index1(email);或
mysql> alter table suser add index index2(email(6))
;
兩種索引的示意圖:
圖 1 email 索引結構
圖 2 email(6) 索引結構
可以看出利用字首索引是可以節省儲存空間的。
但是,可能會增加掃瞄的次數。
比如。有一條sql語句:
select id,name,email from suser where email=
'zhangssxyz@***.com'
;
如果是email 整個字串的索引結構,執行順序:
1 從eamil索引找到『zhangssxyz@***.com』的id2的值
2 回到主建索引找到id2的值的行,加入結果集
3 判斷email索引欄位的下乙個是否等於「zhangssxyz@***.com」,等於重複第二步,否則查詢結束。
如果是email(6) 索引結構,執行順序:
1 從email(6) 索引找到『zhangs』的id1的值
2 從主健索引找到id1的值的那一行,判斷email是否等於「zhangssxyz@***.com」,發現不等於,丟棄記錄
3 從email(6) 索引的下一行查詢,發現等於「zhangs」,取出id2,回到主鍵找到id2的值,發現email等於,將結果放入結果集
4 重複3,直到email(6) 索引的值不等於"zhangs"
但是,區分度比較高的話,
使用字首索引,定義好長度,就可以做到既節省空間,又不用額外增加太多的查詢成本。
我們可以通過統計索引上有多少個不同的值來判斷要使用多長的字首。
mysql>
select count(distinct email) as l from suser;
可以依次檢視4-7個位元組長度不同的值
mysql>
select
count(distinct left(email,4))as l4,
count(distinct left(email,5))as l5,
count(distinct left(email,6))as l6,
count(distinct left(email,7))as l7,
from suser;
對覆蓋索引的影響如果使用了字首索引,就不得不回到主建索引在查詢一次,就無法利用覆蓋索引不需要回表提高效能的優勢。即使字首索引使用了全部的字元竄,因為系統不能確定字首是否包含了完整資訊。
其他方式
1 使用倒序儲存。如果你儲存身份證號的時候把它倒過來存,每次查詢的時候,你可以這麼寫:
mysql>
select field_list from t where id_card = reverse(
'input_id_card_string'
);
實踐中你不要忘記使用 count(distinct) 方法去做個驗證
2 是使用 hash 字段。你可以在表上再建立乙個整數字段,來儲存身份證的校驗碼,同時在這個欄位上建立索引
mysql> alter table t add id_card_crc int unsigned, add index(id_card_crc)
;
由於crc32()可能衝突,所以查詢語句要這麼寫:
mysql>
select field_list from t where id_card_crc=crc32(
'input_id_card_string'
) and id_card=
'input_id_card_string'
索引的長度變成了 4 個位元組,比原來小了很多。
相同: 只支援等值查詢,不支援範圍查詢
區別:1 從占用的額外空間來看,倒序儲存方式在主鍵索引上,不會消耗額外的儲存空間,而 hash 字段方法需要增加乙個字段。當然,倒序儲存方式使用 4 個位元組的字首長度應該是不夠的,如果再長一點,這個消耗跟額外這個 hash 欄位也差不多抵消了。
2 在 cpu 消耗方面,倒序方式每次寫和讀的時候,都需要額外呼叫一次 reverse 函式,而 hash 欄位的方式需要額外呼叫一次 crc32() 函式。如果只從這兩個函式的計算複雜度來看的話,reverse 函式額外消耗的 cpu 資源會更小些。
3 從查詢效率上看,使用 hash 字段方式的查詢效能相對更穩定一些。因為 crc32 算出來的值雖然有衝突的概率,但是概率非常小,可以認為每次查詢的平均掃瞄行數接近 1。而倒序儲存方式畢竟還是用的字首索引的方式,也就是說還是會增加掃瞄行數。
mysql 學習(七)關於字串欄位加索引
整個email欄位新增索引add index index1 email 利用字首長度來新增索引add index index2 email 6 由於 email 6 這個索引結構中每個郵箱欄位都只取前 6 個位元組,所以占用的空間會更小,這就是使用字首索引的優勢,可能會增加額外的記錄掃瞄次數。通過下...
MYSQL索引 學習筆記
索引分類 索引失效 索引帶來的弊端 幫助mysql進行高效查詢的資料結構 有序 在資料之外,資料庫系統還維護著滿足特定查詢演算法的資料結構,這些資料結構以某種方式引用 指向 資料,這樣就可以在這些資料結構上實現高階查詢演算法,這種資料結構就是索引 換言之,索引就是某種資料結構 如下圖所示 左邊是資料...
mysql索引學習筆記
mysql索引學習筆記 1.索引的優劣 優 加快查詢速率 劣 影響對錶的添刪改操作的速率,增大檔案大小 可能索引檔案比資料檔案還大 所以,在往資料庫匯入大量資料之前,應該先暫時刪除索引,資料匯入完成後再統一建立索引。www.2cto.com 2.建立索引的原則 1 不過度索引 2 索引應該建在需要頻...