MySQL的前綴索引你是如何使用的


靈魂3連問:

什么是前綴索引?

前綴索引也叫局部索引,比如給身份證的前 10 位添加索引,類似這種給某列部分信息添加索引的方式叫做前綴索引。

為什么要用前綴索引?

前綴索引能有效減小索引文件的大小,讓每個索引頁可以保存更多的索引值,從而提高了索引查詢的速度。但前綴索引也有它的缺點,不能在 order by 或者 group by 中觸發前綴索引,也不能把它們用於覆蓋索引。

什么情況下適合使用前綴索引?

當字符串本身可能比較長,而且前幾個字符就開始不相同,適合使用前綴索引;相反情況下不適合使用前綴索引,比如,整個字段的長度為 20,索引選擇性為 0.9,而我們對前 10 個字符建立前綴索引其選擇性也只有 0.5,那么我們需要繼續加大前綴字符的長度,但是這個時候前綴索引的優勢已經不明顯,就沒有創建前綴索引的必要了。

 

舉例說明:

當要索引的列字符很多時 索引則會很大且變慢
( 可以只索引列開始的部分字符串 節約索引空間 從而提高索引效率 )

原則: 降低重復的索引值

例如現在有一個地區表

area gdp code
chinaShanghai 100 aaa
chinaDalian 200 bbb
usaNewYork 300 ccc
chinaFuxin 400 ddd
chinaBeijing 500 eee

發現 area 字段很多都是以 china 開頭的
那么如果以前1-5位字符做前綴索引就會出現大量索引值重復的情況
索引值重復性越低 查詢效率也就越高


前綴索引測試

// 創建一個測試表
CREATE TABLE `x_test` (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
  `x_name` varchar(255) NOT NULL,
  `x_time` int(10) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4145025 DEFAULT CHARSET=utf8mb4

// 添加200萬條測試數據
INSERT INTO x_test(x_name,x_time) SELECT CONCAT(rand()*3300102,x_name),x_time FROM x_test WHERE id < 30000;
 
200萬 測試數據
  1. 在無任何索引的情況下隨便查詢一條
    SELECT * FROM x_test WHERE x_name = '1892008.205824857823401.800099203178258.8904820949682635656.62526521254';
    查詢時間:2.253s

  2. 添加前綴索引 ( 以第一位字符創建前綴索引 )
    alter table x_test add index(x_name(1))
    再次查詢相同sql語句
    SELECT * FROM x_test WHERE x_name = '1892008.205824857823401.800099203178258.8904820949682635656.62526521254';
    查詢時間:3.291s
    當使用第一位字符創建前綴索引后 貌似查詢的時間更長了
    因為只第一位字符而言索引值的重讀性太大了
    200萬條數據全以數字開頭那么平均20萬條的數據都是相同的索引值

  3. 重新建立前綴索引 這次以前4位字符來創建
    alter table x_test add index(x_name(4));
    再次查詢相同sql語句
    SELECT * FROM x_test WHERE x_name = '1892008.205824857823401.800099203178258.8904820949682635656.62526521254';
    查詢時間:0.703s
    這次以前4位創建索引 大大減少了索引值的重復性 查詢速度從3秒提升到0.7秒

  4. 200萬條數據都以數字開頭 而0-9排列組合7位則可達到千萬種組合
    也就是以前7位來做索引則不會出現重復索引值的情況了
    alter table x_test add index(x_name(7));
    再次查詢相同sql語句
    SELECT * FROM x_test WHERE x_name = '1892008.205824857823401.800099203178258.8904820949682635656.62526521254';
    查詢時間:0.014s ( 首次執行無緩存狀態下 )


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM