mysql索引 钱缀_【mysql索引】之前缀索引-Go语言中文社区
第零步:簡單說一說
有時候需要索引很長的字符(例如BLOB,TEXT,或者很長的VARCHAR),這樣會使得索引又大又慢。
改良方法有:1.改用哈希索引(這里不講)。2.使用字符串的前幾個字符作為索引(即前綴索引)。
下面具體主要說第2種方法,主要思路就是選擇足夠長的前綴以保證較高的選擇性,同時又不能太長(造成空間浪費)。
所謂選擇性,是指不重復(fù)的索引數(shù)量除以總記錄數(shù),范圍是(0,1],唯一索引之所以查詢效率高,是因為它的選擇性等于1。首先要做的是準(zhǔn)備好足夠的數(shù)據(jù)來進行測試,最簡單的方法是:
我們剛安裝好MySQL的時候,會有一個叫sakila的數(shù)據(jù)庫,這個數(shù)據(jù)庫可以方便我們進行各種練習(xí)。
下面我們直接開始行動~用Navicat打開sakila數(shù)據(jù)庫(沒有Navicat?那就命令行use sakila吧)
第一步:建立測試表及其數(shù)據(jù)
-- 新建一個測試表city_demo,并把表city的數(shù)據(jù)復(fù)制過去
INSERT INTO city_demo SELECT city FROM city;
-- 把表city_demo自身的數(shù)據(jù)復(fù)制5次,即反復(fù)執(zhí)行下面這句語句5次
INSERT INTO city_demo SELECT city FROM city_demo;
-- 將表里面的城市名隨機打亂(這一步生成的結(jié)果會與我之后展示的數(shù)據(jù)有差別,但并不影響分析)
UPDATE city_demo SET city = (SELECT city FROM city ORDER BY RAND() LIMIT 1);
第二步:計算合適的前綴索引長度
有兩種方法計算長度
方法一:
-- 查詢重復(fù)次數(shù)最多的10條完整城市名稱及其數(shù)量(圖1)
SELECT COUNT(*) cnt, city FROM city_demo GROUP BY city ORDER BY cnt DESC LIMIT 10;
-- 查詢重復(fù)次數(shù)最多的10條城市名稱(前3個字符)及其數(shù)量,可以發(fā)現(xiàn):前3個字符的相同數(shù)量過大,不適合做前綴索引(圖2)
SELECT COUNT(*) cnt, LEFT(city,3) pref FROM city_demo GROUP BY pref ORDER BY cnt DESC LIMIT 10;
-- 查詢重復(fù)次數(shù)最多的10條城市名稱(前7個字符)及其數(shù)量,可以發(fā)現(xiàn):前7個字符的相同數(shù)量和完整城市名稱很相近了,可以考慮作為做前綴索引(圖3)
SELECT COUNT(*) cnt, LEFT(city,7) pref FROM city_demo GROUP BY pref ORDER BY cnt DESC LIMIT 10;
圖1:
圖2:
圖3:
方法二:
-- 計算出完整字符串的選擇性(圖4)
SELECT COUNT(DISTINCT city)/COUNT(*) FROM city_demo;
-- 計算各個前綴的選擇性(圖5),然后找出選擇性與圖4相近的
SELECT
COUNT(DISTINCT LEFT(city,3))/COUNT(*) pref3,
COUNT(DISTINCT LEFT(city,4))/COUNT(*) pref4,
COUNT(DISTINCT LEFT(city,5))/COUNT(*) pref5,
COUNT(DISTINCT LEFT(city,6))/COUNT(*) pref6,
COUNT(DISTINCT LEFT(city,7))/COUNT(*) pref7
FROM city_demo;
圖4:
圖5:
不過pref4和pref5是一個陷阱,因為它們看上去已經(jīng)很接近完整字符串的選擇性了,但是我們可以用方法一來看一下:
-- 結(jié)果看圖6
SELECT COUNT(*) cnt, LEFT(city,4) pref4 FROM city_demo GROUP BY pref4 ORDER BY cnt DESC LIMIT 5;
-- 結(jié)果看圖7
SELECT COUNT(*) cnt, LEFT(city,5) pref5 FROM city_demo GROUP BY pref5 ORDER BY cnt DESC LIMIT 5;
圖6:
圖7:
可以看出,前綴4和5的分布還是不均勻的以Sant、South為首的城市仍然比較多,結(jié)合方法一、二,可以建立長度為7的前綴索引了
第三步:建立前綴索引
ALTER TABLE `city_demo` ADD INDEX `idx_city` (`city`(7)) USING BTREE ;
-- 或者這個也行
ALTER TABLE `city_demo` ADD KEY `idx_city` (`city`(7))
-- 又或者直接用Navicat可視化操作也行
前綴索引的缺點
MySQL中無法使用前綴索引進行ORDER BY和GROUP BY,也無法用來進行覆蓋掃描
總結(jié)
以上是生活随笔為你收集整理的mysql索引 钱缀_【mysql索引】之前缀索引-Go语言中文社区的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: mysql分库分区分表怎么做_mysql
- 下一篇: java集合使用_java集合使用初步