mysql-索引使用-列的散列度-01

mysql 查詢優(yōu)化中,索引的使用原則

  • 前提:sys_user 。數(shù)據(jù)340W
CREATE TABLE `sys_user` (
`id`  int(11) NOT NULL AUTO_INCREMENT ,
`user_name`  varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '用戶名' ,
`user_password`  varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '用戶密碼' ,
`phone`  varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '電話號碼' ,
`email`  varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '郵箱' ,
`address`  varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '地址' ,
PRIMARY KEY (`id`),
INDEX `idx_user_name` (`user_name`) USING BTREE 
)
ENGINE=InnoDB
DEFAULT CHARACTER SET=utf8 COLLATE=utf8_general_ci
AUTO_INCREMENT=3409377
ROW_FORMAT=DYNAMIC
;
  • 列的離散度
    在分析索引的使用之前,先看一個必要的概念:列的離散度。
  1. 計算公式:user_name 的離散度
select (select count(distinct(user_name)) from sys_user )/(select count(1) from sys_user);

從上面公式可以看出:列重復(fù)的值越少,離散度越高,重復(fù)的值越多離散度越低。這個和索引有啥關(guān)系?結(jié)論是:離散度越高,在查詢時,掃描的行數(shù)越少,效率越高。原理后面分析,先看現(xiàn)象。

  1. 離散度測試

數(shù)據(jù)量 340W。

數(shù)據(jù).PNG

如上圖所示:email 的數(shù)據(jù)離散度非常低。也就是email 存中很多的重復(fù)的值。

  1. 在沒有使用索引的前提下:查詢
查詢.png
SELECT user_name,email from sys_user where email = '1234@163.com'

運行結(jié)果是,需要2.9s,我們可以使用 explain 分析一下執(zhí)行情況。

EXPLAIN SELECT user_name,email from sys_user where email = '1234@163.com'
掃描結(jié)果.png

從圖中我們可以看到,在沒有使用索引的情況下,查詢條件是email 時,要掃描 310W 行的數(shù)據(jù),幾乎是全表掃描了,所以很慢,用了接近3s 的時間。

  1. 給email 創(chuàng)建索引

ok, 從上面的查詢結(jié)果看,查詢很慢,我們第一反應(yīng)是創(chuàng)建一個索引,ok,現(xiàn)在我們就來創(chuàng)建一個索引。


索引查詢.png

我們看到查詢結(jié)果,結(jié)果明顯只用于0.001s。那么是不是說明離散度的低的列建立索引也能對查詢結(jié)果有明顯的提高呢?先分析explain :


image.png

我們看到,這條語句執(zhí)行只掃描了三行,所以查詢很快。再看一條語句:


image.png

image.png

怎么回事?不是加了索引就會變快嗎?怎么換個值查詢,就又變慢了呢??原因就是掃描了150萬行的數(shù)據(jù)。

  1. 多條件查詢:
SELECT user_name,email, user_password from sys_user where email = '123@163.com' and user_password = '1234569'

查詢結(jié)果:


查詢結(jié)果.png

簡直就是災(zāi)難,明明只有兩條數(shù)據(jù)符合結(jié)果,但是卻用了接近10s 。

explain結(jié)果.png

掃描數(shù)據(jù)庫 157W行數(shù)據(jù)。

  • 結(jié)論:從上面的運行結(jié)果看,表中的email 列數(shù)據(jù)離散度非常低,也就是說重復(fù)度非常高,那么我們就算為email 創(chuàng)建了索引,效果也沒有多么明顯,也就是說,如果想通過索引來優(yōu)化查詢性能的話,創(chuàng)建索引的列的值的重復(fù)度必須要小。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容