- 首页 > 人文 > >
索引一文带你你搞懂索引如何优化( 四 )
另一种不建议建索引的情况是索引的选择性较低 。 所谓索引的选择性(Selectivity) , 是指不重复的索引值(也叫基数 , Cardinality)与表记录数(#T)的比值: IndexSelectivity = Cardinality / #T
- 显然选择性的取值范围为(0, 1]`` , 选择性越高的索引价值越大 , 这是由B+Tree的性质决定的 。 例如 , employees.titles表 , 如果title`字段经常被单独查询 , 是否需要建索引 , 我们看一下它的选择性:
SELECT count(DISTINCT(title))/count(*) ASSelectivity FROMemployees.titles+-------------+| Selectivity |+-------------+|0.0000 |+-------------+
- title的选择性不足0.0001(精确值为0.00001579) , 所以实在没有什么必要为其单独建索引 。
- 有一种与索引选择性有关的索引优化策略叫做前缀索引 , 就是用列的前缀代替整个列作为索引key , 当前缀长度合适时 , 可以做到既使得前缀索引的选择性接近全列索引 , 同时因为索引key变短而减少了索引文件的大小和维护开销 。 下面以employees.employees表为例介绍前缀索引的选择和使用 。
- 假设employees表只有一个索引 , 那么如果我们想按名字搜索一个人 , 就只能全表扫描了:
EXPLAIN SELECT * FROM employees.employees WHERE first_name="Eric"AND last_name="Anido"+----+-------------+-----------+------+---------------+------+---------+------+--------+-------------+| id |select_type | table|type | possible_keys |key| key_len |ref| rows|Extra|+----+-------------+-----------+------+---------------+------+---------+------+--------+-------------+|1 | SIMPLE|employees | ALL|NULL| NULL |NULL| NULL | 300024 | Using where |+----+-------------+-----------+------+---------------+------+---------+------+--------+-------------+
- 如果频繁按名字搜索员工 , 这样显然效率很低 , 因此我们可以考虑建索引 。 有两种选择 , 建或<first_name, last_name> , 看下两个索引的选择性:
SELECT count(DISTINCT(first_name))/count(*) ASSelectivity FROMemployees.employees+-------------+| Selectivity |+-------------+|0.0042 |+-------------+SELECT count(DISTINCT(concat(first_name, last_name)))/count(*) AS Selectivity FROM employees.employees+-------------+| Selectivity |+-------------+|0.9313 |+-------------+
- 显然选择性太低 , ``<first_name, last_name>选择性很好 , 但是first_name和last_name加起来长度为30 , 有没有兼顾长度和选择性的办法?可以考虑用first_name和last_name的前几个字符建立索引 , 例如<first_name, left(last_name, 3)>` , 看看其选择性:
SELECT count(DISTINCT(concat(first_name, left(last_name, 3))))/count(*) ASSelectivity FROMemployees.employees+-------------+| Selectivity |+-------------+|0.7879 |+-------------+
- 选择性还不错 , 但离0.9313还是有点距离 , 那么把last_name前缀加到4:
SELECT count(DISTINCT(concat(first_name, left(last_name, 4))))/count(*) ASSelectivity FROMemployees.employees+-------------+| Selectivity |+-------------+|0.9007 |+-------------+
- 这时选择性已经很理想了 , 而这个索引的长度只有18 , 比<first_name, last_name>短了接近一半 , 我们把这个前缀索引建上:
推荐阅读
-
-
『GO野历史』为何就考不中功名呢?,蒲松龄能够写出流传至今的《聊斋志异》
-
-
母象间发生矛盾 受“夹板气”的公象:你们不要再打啦!
-
-
WE UNIQUE唯优加|《OMG玩美咖》赵露思嫩得掐出水,推荐唯优加月光肌
-
简简科技|复旦邱锡鹏团队最新成果fastHan:基于BERT的中文NLP集成工具
-
上观新闻|偏爱“小份菜”上海拿全国第一,记者试点外卖、堂吃套餐发现各种“减量降价”
-
面霜|非洲人美白成瘾,用面霜会伤脸算什么,能做“人上人”才是关键
-
蓝莓评测称十城全家售过期食品 以后买东西这些细节不能忽视
-
-
雷帝触网 国美沦为京东拼多多小弟,黄光裕获假释:失去黄金10年
-
驾驶|那些还在吹捧手动挡的“杠精”,又有多少人买了手动挡?
-
单场直播5亿销售额,离婚不是他的错,为何堕落去带货?
-
|恭喜Bin!疑似恋爱,女生不是网红脸!2人公开互关,国服疯狂双排
-
罗志祥|还是朋友!罗志祥自曝与周扬青仍有联络,否认蝴蝶姐姐嫁内地医生
-
面霜■什么面霜好用?4款平价面霜种草,平价又好用,都是你买得起的
-
「美国约100万餐饮人失业」美国新冠肺炎确诊超475万,美国约100万餐饮人失业
-
华为年薪201万天才少年回应|华为年薪201万天才少年回应
-
一角车吧|比宝马3系、奔驰C级更有吸引力,买不起帕拉梅拉选它!破百仅需4S