既然索引可以加快查询速度,那么是不是只要是查询语句需要,就建上索引?答案是否定的。因为索引虽然加快了查询速度,但索引也是有代价的:索引文件本身要消耗存储空间,同时索引会加重插入、删除和修改记录时的负担,另外,MySQL在运行时也要消耗资源维护索引,因此索引并不是越多越好。一般两种情况下不建议建索引。

第一种情况是表记录比较少,例如一两千条甚至只有几百条记录的表,没必要建索引,让查询做全表扫描就好了。至于多少条记录才算多,这个个人有个人的看法,我个人的经验是以2000作为分界线,记录数不超过 2000可以考虑不建索引,超过2000条可以酌情考虑索引。

另一种不建议建索引的情况是索引的选择性较低。所谓索引的选择性(Selectivity),是指不重复的索引值(也叫基数,Cardinality)与表记录数(#T)的比值:

~~~

Index Selectivity = Cardinality / #T

~~~

显然选择性的取值范围为(0, 1],选择性越高的索引价值越大,这是由B+Tree的性质决定的。例如,上文用到的employees.titles表,如果title字段经常被单独查询,是否需要建索引,我们看一下它的选择性:

~~~

SELECT count(DISTINCT(title))/count(*) AS Selectivity FROM employees.titles;

+-------------+

| Selectivity |

+-------------+

| 0.0000 |

+-------------+

~~~

title的选择性不足0.0001(精确值为0.00001579),所以实在没有什么必要为其单独建索引。

有一种与索引选择性有关的索引优化策略叫做前缀索引,就是用列的前缀代替整个列作为索引key,当前缀长度合适时,可以做到既使得前缀索引的选择性接近全列索引,同时因为索引key变短而减少了索引文件的大小和维护开销。下面以employees.employees表为例介绍前缀索引的选择和使用。

从图12可以看到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 |

+----+-------------+-----------+------+---------------+------+---------+------+--------+-------------+

~~~

如果频繁按名字搜索员工,这样显然效率很低,因此我们可以考虑建索引。有两种选择,建或,看下两个索引的选择性:

~~~

SELECT count(DISTINCT(first_name))/count(*) AS Selectivity FROM employees.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加起来长度为30,有没有兼顾长度和选择性的办法?可以考虑用first_name和last_name的前几个字符建立索引,例如,看看其选择性:

~~~

SELECT count(DISTINCT(concat(first_name, left(last_name, 3))))/count(*) AS Selectivity FROM employees.employees;

+-------------+

| Selectivity |

+-------------+

| 0.7879 |

+-------------+

~~~

选择性还不错,但离0.9313还是有点距离,那么把last_name前缀加到4:

~~~

SELECT count(DISTINCT(concat(first_name, left(last_name, 4))))/count(*) AS Selectivity FROM employees.employees;

+-------------+

| Selectivity |

+-------------+

| 0.9007 |

+-------------+

~~~

这时选择性已经很理想了,而这个索引的长度只有18,比短了接近一半,我们把这个前缀索引 建上:

~~~

ALTER TABLE employees.employees

ADD INDEX `first_name_last_name4` (first_name, last_name(4));

~~~

此时再执行一遍按名字查询,比较分析一下与建索引前的结果:

~~~

SHOW PROFILES;

+----------+------------+---------------------------------------------------------------------------------+

| Query_ID | Duration | Query |

+----------+------------+---------------------------------------------------------------------------------+

| 87 | 0.11941700 | SELECT * FROM employees.employees WHERE first_name='Eric' AND last_name='Anido' |

| 90 | 0.00092400 | SELECT * FROM employees.employees WHERE first_name='Eric' AND last_name='Anido' |

+----------+------------+---------------------------------------------------------------------------------+

~~~

性能的提升是显著的,查询速度提高了120多倍。

前缀索引兼顾索引大小和查询速度,但是其缺点是不能用于ORDER BY和GROUP BY操作,也不能用于Covering index(即当索引本身包含查询所需全部数据时,不再访问数据文件本身)。

mysql索引 钱缀_-MySQL索引背后的数据结构及算法原理--索引选择性与前缀索引相关推荐

  1. MySQL索引背后的数据结构及算法原理【转】

    http://blog.codinglabs.org/articles/theory-of-mysql-index.html MySQL索引背后的数据结构及算法原理[转] 摘要 本文以MySQL数据库 ...

  2. MySQL索引背后的数据结构及算法原理--转

    MySQL索引背后的数据结构及算法原理 作者 张洋 | 发布于 2011-10-18 MySQL 索引 B树 优化 原文地址:http://blog.codinglabs.org/articles/t ...

  3. MySQL 索引背后的数据结构及算法原理

    本文转载自http://blog.jobbole.com/24006/ 摘要 本文以MySQL数据库为研究对象,讨论与数据库索引相关的一些话题.特别需要说明的是,MySQL支持诸多存储引擎,而各种存储 ...

  4. mysql 按时间累计计算_精通MySQL索引背后的数据结构及算法原理

    本文以MySQL数据库为研究对象,讨论与数据库索引相关的一些话题.特别需要说明的是,mysql支持诸多存储引擎,而各种存储引擎对索引的支持也各不相同,因此MySQL数据库支持多种索引类型,如BTree ...

  5. mysql数据库算法_数据库:MySQL索引背后的数据结构及算法原理【转】

    原文:http://blog.codinglabs.org/articles/theory-of-mysql-index.html 摘要 本文以MySQL数据库为研究对象,讨论与数据库索引相关的一些话 ...

  6. MySQL索引背后的数据结构及算法原理zz

    摘要 本文以MySQL数据库为研究对象,讨论与数据库索引相关的一些话题.特别需要说明的是,MySQL支持诸多存储引擎,而各种存储引擎对索引的支持 也各不相同,因此MySQL数据库支持多种索引类型,如B ...

  7. 【转载】MySQL索引背后的数据结构及算法原理

    本文转载自http://blog.jobbole.com/24006/ 摘要 本文以MySQL数据库为研究对象,讨论与数据库索引相关的一些话题.特别需要说明的是,MySQL支持诸多存储引擎,而各种存储 ...

  8. MySQL索引背后的数据结构及算法原理----惊叹的深入

    原文出处: 张洋    摘要 本文以MySQL数据库为研究对象,讨论与数据库索引相关的一些话题.特别需要说明的是,MySQL支持诸多存储引擎,而各种存储引擎对索引的支持也各不相同,因此MySQL数据库 ...

  9. MySQL索引背后的数据结构及算法原理-转

    转  http://www.codinglabs.org/html/theory-of-mysql-index.html 摘要 本文以MySQL数据库为研究对象,讨论与数据库索引相关的一些话题.特别需 ...

最新文章

  1. Happy Birthday
  2. 《.NET框架程序设计》第2章 第3章 读后感
  3. 如何在Windows中打开和使用命令提示符
  4. python面向对象编程从零开始_Python面向对象编程从零开始,从没对象到有对象
  5. 继续!面试继续!Netty dubbo的通信方式
  6. Kafka消费者的使用和原理
  7. 在修改css特效时,需要注意的问题。(对寄存的影响,引用的位置)
  8. struts2 action 返回类型分析
  9. Java8与传统的日期和时间类详解
  10. 不要犹豫 了解这些即可玩转阿里云ODPS
  11. 【三石jQuery视频教程】01.图片循环展示
  12. 数据结构 | 单链表SingleList【带你从浅入深真正搞懂链表】
  13. 数据分析——泰坦尼克号乘客数据集
  14. mysql与gbase获取行号_mysql/gbase数据库全库库表记录数统计
  15. 《元宇宙十大技术》感谢乔卫兵等6位为出版做出巨大贡献
  16. NPOI导出Excel并下载到客户端
  17. MySQL命令简单应用
  18. 京冀41所医院和急救中心成为北京冬奥会定点医院
  19. Python 线程启动和关闭
  20. 【NOWCODE SEVEN】:二分查找/排序

热门文章

  1. 2021春季学期-创新设计与实践-课程结构设计
  2. 机械臂底层通信协议说明
  3. 2020年第十五届全国大学生智能汽车竞赛山东赛区成绩统计
  4. 国内与国外摄影爱好者的区别
  5. java简单springboot系统_Springboot系列 3 - 建立简单的用户登录系统
  6. otf和ctf的意义_光学信息技术原理及应用 OTF与CTF的比较与计算.ppt
  7. PHP tcp短链接,http请求怎样实现TCP长连接、短连接
  8. 计算机科学与技术专业术语
  9. Vivado 随笔(5) 行为仿真(Behavior Simulation)相关事宜?
  10. Xinlinx 7系列 FPGA 总览