mysql建立高效索引分析


一、如何建立理想的索引?

  • 查詢頻繁度
  • 區分度
  • 索引長度
  • 覆蓋字段

1.1區分度

假設100萬用戶,性別基本上男/女各為50W, 區分度就低。

1.2長度小

索引長度直接影響索引文件的大小,影響增刪改的速度,並間接影響查詢速度(占用內存多).

1.3區分度高,長度小

如何讓區分度高,而長度小?

可以針對列中的值,從左往右截取部分,來建索引

  • 截的越短,重復度越高,區分度越小, 索引效果越不好。
  • 截的越長,重復度越低,區分度越高,索引效果越好,但帶來的影響也越大–增刪改變慢,並間影響查詢速度。

所以,我們要在 區分度 + 長度兩者上,取得一個平衡。慣用手法:截取不同長度,並測試其區分度。
假設我們有一張表:英語4級的單詞表,里面有13324條記錄,我們怎么給name字段加索引呢?

如果計算區分度?
截取單詞第1位的不重復數:

select count(distinct left(name,1)) from dict

總的數量:

select count(*) from dict

區分度:不重復數/總的數量,sql語句如下:

select (select count(distinct left(name,1)) from dict) / (select count(*) from dict) as rate;

然后按照這樣的步驟把其他長度所對應的區分度給找出來,看一個這個圖表,可以知道當長度為11的時候重復度僅僅為1%,我們可以考慮建立11位長的索引

alter table dict add index name name(11);

1.4左前綴不好區分的情況

如url列
http://www.baidu.com

http://www.web-bc.cn
列的前11個字符都是一樣的,不易區分, 可以用如下2個辦法來解決

1.4.1把列內容倒過來存儲,這樣左前綴區分度大,並建立索引

moc.udiab.www//:ptth

nc.cb-bew.www//😕/ptth

1.4.2偽hash索引效果

同時存url和url_hash列,建表如下

create table t10 (
id int primary key,
url char(60) not null default ''
);
#插入數據
insert into t10 values
(1,'http://www.baidu.com'),
(2,'http://www.sina.com'),
(3,'http://www.sohu.com.cn'),
(4,'http://www.onlinedown.net'),
(5,'http://www.gov.cn');
#修改表結構,添加urlcrc列
alter table t10 add urlcrc int unsigned not null;

在存儲的時候,將url對應的crc32碼一同插入到數據庫中,然后按照urlcrc字段建立索引,然后查找的時候,我們在業務層中將對應的url轉換為crc32進行查找,就可以利用上索引了。
因為crc的結果是32位int無符號數,因此當數據超過40億,也會有重復,但這是值得的.(索引長度為int4個字節)

多列索引

多列索引的考慮因素—列的查詢頻率,列的區分度,注意一定要結合實際業務場景
以ecshop商城為例,goods表中的cat_id,brand_id,做多列索引,從區分度看,brand_id區分度更高,但從商城的實際業務業務看,顧客一般先選大分類->小分類->品牌,最終選擇建立2個索引:
(1)index(cat_id,brand_id)

(2)index(cat_id,shop_price)
甚至可以再加(3)index(cat_id,brand_id,shop_price),3個冗余索引。但(3)中的前2列和(1)中的前2列一樣,所以可以再去掉(1),建立2個索引


免責聲明!

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



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