一:概述
- 我有一個需求是需要郵箱登錄的,
- mysql> select f1, f2 from SUser where email='xxx';
- 我們知道,如果不在 email 上建立索引,那么將會走全表掃描。
- 於是,我們有兩種建立方式
- mysql> alter table SUser add index index1(email); // 普通索引
- mysql> alter table SUser add index index2(email(6)); // 前綴索引
二:普通索引和前綴索引的區別?
- 我們看看,他們建立的索引樹有什么不同
-
- 從圖中你可以看到
- 由於 email(6) 這個索引結構中每個郵箱字段都只取前 6 個字節(即:zhangs),所以占用的空間會更小,這就是使用前綴索引的優勢。
三:普通索引和前綴索引查詢流程的不同?
- 舉例
- select id,name,email from SUser where email='zhangssxyz@xxx.com';
- 普通索引
- 從索引樹找到滿足索引值是 'zhangssxyz@xxx.com' 的這條記錄,取得 ID2 的值;
- 到主鍵上查到主鍵值是 ID2 的行,判斷 email 的值是正確的,將這行記錄加入結果集;
- 取索引樹上剛剛查到的位置的下一條記錄,發現已經不滿足 email='zhangssxyz@xxx.com'的條件了,循環結束。
- 這個過程中,只需要回主鍵索引取一次數據,所以系統認為只掃描了一行。
- 前綴索引
- 索引樹找到滿足索引值是 'zhangs' 的記錄,找到的第一個是 ID1;
- 到主鍵上查到主鍵值是 ID1 的行,判斷出 email 的值不是'zhangssxyz@xxx.com',這行記錄丟棄;
- 取到剛剛查到的位置的下一條記錄,發現仍然是’zhangs‘,取出 ID2,再到 ID 索引上取整行然后判斷,這次值對了,將這行記錄加入結果集;
- 重復上一步,直到取到的值不是'zhangs'時,循環結束。
- 在這個過程中,要回主鍵索引取 4 次數據,也就是掃描了 4 行。
- 結論
- 通過這個對比,你很容易就可以發現,使用前綴索引后,可能會導致查詢語句讀數據的次數變多。
四:區分度
- 通過上面的測試,我們知道,是否會導致查詢變多,主要是建立前綴索引的區分度的選擇。
- SELECT COUNT(DISTINCT LEFT(column_name, $length)) / COUNT(*) FROM table_name; // 查詢區分度
五: 前綴索引對覆蓋索引的影響
- 使用前綴索引后,無法在使用覆蓋索引,面對查詢條件,可能需要回表操作。
六:面對字符串,我們也可以采取其他方式存儲
- hash
- bit 位
- 倒序
- 等等