精心总结十三条建议,帮你创建更合适的MySQL索引

打印 上一主题 下一主题

主题 877|帖子 877|积分 2631

上篇文章讲到使用MySQL的Explain命令可以分析SQL性能瓶颈,优化SQL查询,以及查看是否用到了索引。
我们都知道创建索引可以提高查询效率,但是具体该怎么创建索引?
哪些字段适合创建索引?
哪些字段又不适合创建索引?
本文跟大家一块学习一下如何创建合适数据库索引。
1. MySQL索引的分类

在创建索引之前了解一下MySQL有哪些索引,然后我们才能选择合适的索引。
常见的索引有,普通索引、唯一索引、主键索引、联合索引、全文索引等。
普通索引

普通索引就是最基本的索引,没有任何限制。
可以使用命令创建普通索引:
  1. ALTER TABLE `table_name` ADD INDEX index_name (`column`);
复制代码
唯一索引

与普通索引不同,唯一索引的列值必须唯一,允许为null。
创建方式是这样的:
  1. ALTER TABLE `table_name` ADD UNIQUE index_name (`column`);
复制代码
主键索引

主键索引是一种特殊的唯一索引,并且一张表只有一个主键,不允许为null。
创建方式是这样的:
  1. ALTER TABLE `table_name` ADD PRIMARY KEY (`column`);
复制代码
联合索引

联合索引是同时在多个字段上创建索引,查询效率更高。
创建方式是这样的:
  1. ALTER TABLE `table_name` ADD INDEX index_name (`column1`, `column2`, `column3`);
复制代码
全文索引

全文索引主要用来匹配字符串文本中关键字。
当需要字符串中是否包含关键字的时候,我们一般用like,如果是以%开头的时候,则无法用到索引,这时候就可以使用全文索引了。
创建方式是这样的:
  1. ALTER TABLE `table_name` ADD FULLTEXT (`column`);
复制代码
2. 哪些字段适合创建索引?

我总结了有以下几条:
2.1 频繁查询的字段适合创建索引

一张表的字段总会有冷热之分,很明显那些频繁使用的字段更适合为它创建索引。
2.2 在where和on条件出现的字段优先创建索引

为什么不是在select后面出现的字段优先创建索引?
因为查询SQL会先匹配on和where条件的字段,具体的匹配顺序是这样的:
from > on > join > where > group by > having > select > distinct > order by > limit
2.3 区分度高的字段适合创建索引

比如对于一张用户表来说,生日比性别的区分度更高,更适合创建索引。
可以使用下面的方式手动统计一下,每个字段的区分度,值越大,区分度越高:
  1. select
  2.     count(distinct birthday)/count(*),
  3.     count(distinct gender)/count(*)
  4. from user;
复制代码

对于已经创建好的索引,我们还可以使用MySQL命令查看每个索引的区分度排名:

图中Cardinality列表示索引的区分度排名,也被称为基数。
2.4 有序的字段适合创建索引

有序的字段在插入数据库的过程中,仍能保持B+树的索引结构,不需要频繁更新索引文件,性能更好。
3. 哪些字段不合适创建索引?

说完哪些字段适合创建索引,就有不适合创建索引的的字段。
3.1 区分度低的字段不适合创建索引。

刚才说了用户表中性别的区分度较低,不如生日字段适合创建索引。
3.2 频繁更新的字段不适合创建索引

更新字段的过程中,需要维护B+树结构,会频繁更新索引文件,降低SQL性能。
3.3 过长的字段不适合创建索引

过长的字段会占用更多的空间,不适合创建索引。
3.4 无序的字段不适合创建索引

无序的字段在插入数据库的过程中,为了维护B+树索引结构,需要频繁更新索引文件,性能较差。
4. 创建索引的其他注意事项

4.1 优先使用联合索引

查询的时候,联合索引比普通索引能更精准的匹配到所需数据。

图中就是在(age,name)两个字段上建立的联合索引,在B+树中的存储结构。
可以看出,是先age排序,age相等的数据,再按name排序。
对于这条查询SQL:
  1. select age,name from user where age=18 and name='李四';
复制代码
联合索引只需一次就可以查到所需数据,如果我们只在age字段上建立索引,会先匹配到age=18的三条数据,然后再逐个遍历,效率更差,所以平时应该优先使用联合索引。
4.2 使用联合索引时,区分度的字段放前面

这样可以减少查询次数,更快地匹配到所需数据。
4.3 过长字符串可以使用前缀索引

比如在匹配用户地址的时候,如果乡镇已经能区分大部分用户了,就没必要精确到街道小区了。
创建普通索引的时候,指定索引长度,就可以创建前缀索引了。
  1. ALTER TABLE `user` ADD INDEX idx_address (address(3));
复制代码
4.4 值唯一的字段,使用唯一索引

使用唯一索引,可以避免程序bug导致产生重复数据。
4.5 排序和分组字段也尽量创建索引

在order by和group by中的字段也尽量创建索引,避免使用文件排序,可以使用索引排序提供性能。
4.6 避免创建过多索引

索引好用,适度即可。创建过多的索引,会占用更多存储空间,也会严重影响SQL性能,每次更新SQL,都需要更新大量索引文件,得不偿失。
知识点总结:


文章持续更新,可以微信搜一搜「 一灯架构 」第一时间阅读更多技术干货。

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

锦通

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表