- 首页 > 资讯 > 科技 > >
索引|一文带你你搞懂索引如何优化( 四 )
第一种情况是表记录比较少 , 例如一两千条甚至只有几百条记录的表 , 没必要建索引 , 让查询做全表扫描就好了 。 至于多少条记录才算多 , 这个个人有个人的看法 , 我个人的经验是以2000作为分界线 , 记录数不超过 2000可以考虑不建索引 , 超过2000条可以酌情考虑索引 。 另一种不建议建索引的情况是索引的选择性较低 。 所谓索引的选择性(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 |+-------------+
推荐阅读
-
-
【】美国球后小威确认8月“复工” 参加女网重启首场赛事
-
美国新冠肺炎确诊超422万例发生什么事了?美国新冠肺炎确诊超422万例具体情况
-
-
思尔福|第2届“智慧之星”中国智慧零售行业年度评选(2019年)获奖榜单正式出炉!
-
豪门■真正的TWINS组合,做歌手失败,如今一个嫁豪门,一个做地产商
-
虎扑足球▲泰晤士报:孙兴慜训练计划里含实弹演习和一场化学战训练
-
余慕莲|“香港最丑女星”余慕莲近照曝光,曾因肺纤维化屡传病危
-
-
挖贝网营业收入增长,恒实股份2019年盈利1693.07万增长33%
-
-
调饺子馅,牢记“3技巧2不要”,无论什么馅,都鲜嫩入味,超香
-
近段时间感情受挫,工作上由于内向不善于沟通,凡事心里压抑,一个人闷闷不乐,身边找不到朋友诉说。求助?
-
-
阿里巴巴|马云放大招,万亿“巨头”上市!阿里:做一家102年的好公司!
-
-
-
小李车评李建红|一般人压不住,红旗H9,到底准备卖给谁?,气场太强
-
-
一人拖垮整个综艺!她堪称《我们的美好生活》败笔,杨紫也带不动