- 首页 > 资讯 > 科技 > >
索引|一文带你你搞懂索引如何优化( 四 )
第一种情况是表记录比较少 , 例如一两千条甚至只有几百条记录的表 , 没必要建索引 , 让查询做全表扫描就好了 。 至于多少条记录才算多 , 这个个人有个人的看法 , 我个人的经验是以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类药明确不纳入《药品目录》
-
京雄高速建设“无人驾驶专用车道” 北京至雄安将实现1小时通达
-
『明儿小厨』原创 晚餐做3个菜,简单易做营养高,搭配一碗低糖饭,好吃营养身体棒
-
汽车桌|看了新规定,车主:还是原来的好,取消15年强制报废规定
-
-
-
【再不努力】但有“三不”,吃错了不仅没营养,还危害健康,香蕉好吃营养高
-
光明网-《光明日报》|扶贫题材剧要传递支撑“新乡村”持续发展的内在力量
-
-
-
懂车后|价格再低也不要心动,新手朋友注意,老司机都不敢碰的几类二手车
-
沐木李|才是真正的幸福,李子柒的择偶观告诉女人:活成自己喜欢的样子
-
-
三木|冬季里三木和母亲的穿搭像姐妹,优雅时尚还显高级,秘诀就是这些
-
-
己所不欲,勿施于人,人所不欲,勿强于人?己所不欲,勿施于人 己所欲,更勿施于人
-
-
纪律|党课大讲堂丨学习《纪律处分条例》和《廉洁自律准则》,争当守法、廉洁的党员干部模范
-
-