上篇文章讲到使用MySQL的Explain命令可以分析SQL性能瓶颈,优化SQL查询,以及查看是否用到了索引。

我们都知道创建索引可以提高查询效率,但是具体该怎么创建索引?

哪些字段适合创建索引?

哪些字段又不适合创建索引?

本文跟大家一块学习一下如何创建合适数据库索引。

1. MySQL索引的分类

在创建索引之前了解一下MySQL有哪些索引,然后我们才能选择合适的索引。

常见的索引有,普通索引、唯一索引、主键索引、联合索引、全文索引等。

普通索引

普通索引就是最基本的索引,没有任何限制。

可以使用命令创建普通索引:

ALTER TABLE `table_name` ADD INDEX index_name (`column`);

唯一索引

与普通索引不同,唯一索引的列值必须唯一,允许为null。

创建方式是这样的:

ALTER TABLE `table_name` ADD UNIQUE index_name (`column`);

主键索引

主键索引是一种特殊的唯一索引,并且一张表只有一个主键,不允许为null。

创建方式是这样的:

ALTER TABLE `table_name` ADD PRIMARY KEY (`column`);

联合索引

联合索引是同时在多个字段上创建索引,查询效率更高。

创建方式是这样的:

ALTER TABLE `table_name` ADD INDEX index_name (`column1`, `column2`, `column3`);

全文索引

全文索引主要用来匹配字符串文本中关键字。

当需要字符串中是否包含关键字的时候,我们一般用like,如果是以%开头的时候,则无法用到索引,这时候就可以使用全文索引了。

创建方式是这样的:

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 区分度高的字段适合创建索引

比如对于一张用户表来说,生日比性别的区分度更高,更适合创建索引。

可以使用下面的方式手动统计一下,每个字段的区分度,值越大,区分度越高:

select
count(distinct birthday)/count(*),
count(distinct gender)/count(*)
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:

select age,name from user where age=18 and name='李四';

联合索引只需一次就可以查到所需数据,如果我们只在age字段上建立索引,会先匹配到age=18的三条数据,然后再逐个遍历,效率更差,所以平时应该优先使用联合索引。

4.2 使用联合索引时,区分度的字段放前面

这样可以减少查询次数,更快地匹配到所需数据。

4.3 过长字符串可以使用前缀索引

比如在匹配用户地址的时候,如果乡镇已经能区分大部分用户了,就没必要精确到街道小区了。

创建普通索引的时候,指定索引长度,就可以创建前缀索引了。

ALTER TABLE `user` ADD INDEX idx_address (address(3));

4.4 值唯一的字段,使用唯一索引

使用唯一索引,可以避免程序bug导致产生重复数据。

4.5 排序和分组字段也尽量创建索引

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

4.6 避免创建过多索引

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

知识点总结:

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

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

  1. 10条建议帮助你创建更好的jQuery插件

    本文总结了帮助你创建更好jQuery插件的10条建议.分享给大家供大家参考.具体说明如下: 在开发过很多 jQuery 插件以后,我慢慢的摸索出了一套开发jQuery插件比较标准的结构和模式.这样我就 ...

  2. 转:10条建议让你创建更好的jQuery插件

    在开发过很多 jQuery 插件以后,我慢慢的摸索出了一套开发jQuery插件比较标准的结构和模式.这样我就可以 copy & paste 大部分的代码结构,只要专注最主要的逻辑代码就行了.使 ...

  3. 10 条建议让你创建更好的 jQuery 插件

    在开发过很多 jQuery 插件以后,我慢慢的摸索出了一套开发jQuery插件比较标准的结构和模式.这样我就可以 copy & paste 大部分的代码结构,只要专注最主要的逻辑代码就行了. ...

  4. 10条建议让你创建更好的jQuery插件

    在开发过很多 jQuery 插件以后,我慢慢的摸索出了一套开发jQuery插件比较标准的结构和模式.这样我就可以 copy & paste 大部分的代码结构,只要专注最主要的逻辑代码就行了.使 ...

  5. 10条建议让你创建更好的jQuery插件(转载)

    为了避免重复造轮子,自己手动开发jquery 插件,让小组其他成员可以直接使用.学习开发中,看到Phillip Senn 写的 关于jquery 插件开发注意10点,转载之! ------------ ...

  6. 精心整理16条MySQL使用规范,减少80%问题,推荐分享给团队

    上篇文章介绍了如何创建合适的MySQL索引,今天再一块学一下如何更规范.更合理的使用MySQL? 合理规范的使用MySQL,可以大大减少开发工作量和线上问题,并提升SQL查询性能. 我精心总结了这16 ...

  7. MySQL如何创建一个好索引?创建索引的5条建议【宇哥带你玩转MySQL 索引篇(三)】

    MySQL如何创建一个好索引?创建索引的5条建议 过滤效率高的放前面 对于一个多列索引,它的存储顺序是先按第一列进行比较,然后是第二列,第三列...这样.查询时,如果第一列能够排除的越多,那么后面列需 ...

  8. 提高Axure设计效率的10条建议

    http://www.woshipm.com/ucd/92153.html Axure 是创建软件原型的快速有力的工具.上手很容易,但是,其中存在一个危险.这款软件是如此的直观以至于很多用户可以在没有 ...

  9. 提高Axure设计效率的10条建议 (转)

    Axure 是创建软件原型的快速有力的工具.上手很容易,但是,其中存在一个危险.这款软件是如此的直观以至于很多用户可以在没有接受过任何正式培训的情况下进行使用.他们可能不知道的是他们可能没有以恰当的方 ...

随机推荐

  1. mybatis plus 增删改自动填充字段值

    说明 本文实现以下需求效果 创建数据时自动填充 createUserId 和 createTime 更新数据时自动填充 updateUserId 和 updateTime(每次修改都自动填充新的 up ...

  2. linux篇-Centos7jdk安装

    2.1查看现有JDK #rpm -qa|grep jdk (如果有其他版本的JDK建议卸载) 卸载其他版本的JDK命令 #yum –y remove java-1.6.0 #yum –y remov ...

  3. 第06组Alpha冲刺总结

    目录 1. 基本情况 2. 思考与总结 2.1. 设想和目标 2. 计划 3. 资源 4. 变更管理 5. 设计/实现 6. 测试/发布 7. 团队的角色,管理,合作 8. 总结 3. 敏捷开发 1. ...

  4. 附001.Python多版本环境管理

    一 环境背景 由于Python的版本过多,且不同版本之间差异性较大.同时又因系统底层需要调用当前版本Python,所以不能随意变更当前系统Python版本.因此,在多版本共存的情况下,Python多环 ...

  5. iphone苹果手机拼健康码行程码教程

    因为疫情原因,不管是上班,还是上学,各公司和学校都要求提供全家人的健康码和行程码,并弄成一张拼图,这样方便统计!这就苦了广大用苹果手机的朋友们了,因为苹果手机没有自带的拼图软件. 下面我就教大家一个非 ...

  6. GDKOI 2021 Day1 PJ 爆炸记

    早上睡到 7:10 分才想起今天有 GDKOI ,赶紧去买了一个面包赶去机房 发现隔壁的大奆都过来了.比赛时由于昨晚一直没睡好,打了两个小时的哈欠 T1 :暴力模拟 根据 \(r\) 和 \(c\) ...

  7. 【物联网天线选择攻略】2.4GHz 频段增益天线模块设备选择

     天线模块设备(antenna)是一种能量变换器,它把传输线上传播的导行波,变换成在无界媒介中传播的电磁波,或者进行相反的变换.对于设计一个应用于射频系统中的小功率.短距离的2.4GHz无线收发设备, ...

  8. 开始讨论离散型随机变量吧!《考研概率论学习之我见》 -by zobol

    上一文中,笔者给出了随机变量的基本定义:一个可测映射,从结果空间到实数集,我们的目的是为了引入函数这个数学工具到考研概率论中,但是我们在现实中面对的一些事情结果,映射而成的随机变量和其对应的概率值,并 ...

  9. python新建一个目录

    源码部分 import os # 创建目录 def mkdir(path): isExists = os.path.exists(path) if not isExists: os.makedirs( ...

  10. Spring Data JPA系列3:JPA项目中核心场景与进阶用法介绍

    大家好,又见面了. 到这里呢,已经是本SpringData JPA系列文档的第三篇了,先来回顾下前面两篇: 在第1篇<Spring Data JPA系列1:JDBC.ORM.JPA.Spring ...