上篇文章介绍了如何创建合适的MySQL索引,今天再一块学一下如何更规范、更合理的使用MySQL?

合理规范的使用MySQL,可以大大减少开发工作量和线上问题,并提升SQL查询性能。

我精心总结了这16条MySQL规约,分享给大家,欢迎评论指正。

1. 禁止使用select *

阿里开发规范中,有这么一句话:

**select *** 会查询表中所有字段,如果表中的字段有更改,必须修改SQL语句,不然就会执行错误。

查询出非必要的字段,徒增磁盘IO和网络延迟。

2. 用小表驱动大表

关联查询的时候,先用小表查到结果,再用结果去大表查询,可以大大减少连接次数。

比如我们要查询某个部门下的员工,由于部门数量远远小于员工数量。我们可以把部门表当作驱动表,员工表当作被驱动表。

查询SQL类似这样:

select * from department
inner join employee
on department.id=employee.department_id
where department_name='部门1';

3. join关联表不宜过多

join关联表禁止超过3张,join关联过多,不但会增加查询时间,降低查询性能,还会产生临时表缓存结果数据,推荐拆成多条小SQL执行。

另外关联字段的类型一定要保持一致,并且在每张表都要建立关联字段的索引。

4. 禁止使用左模糊或者全模糊查询

当我们在SQL查询使用左模糊或者全模糊匹配的时候,类似下面这样:

# 左模糊查询
select * from user where name='%一灯';
# 全模糊查询
select * from user where name='%一灯%';

根据B+树的特性,即使我们在name字段上建立了索引,查询的时候也是无法用到索引的。

5. 索引访问类型至少达到range级别

索引访问类型常见的有这几个级别,从上到下,性能由好到差。

要求SQL索引访问类型至少要达到range级别,最好到const级别。

6. 更优雅的使用联合索引

由于联合索引有最左匹配原则,所以需要优先把区分度高的字段放在最左边第一列。

比如要统计用户表中生日字段和性别字段区分度,可以这样统计:

select
count(distinct birthday)/count(*),
count(distinct gender)/count(*)
from user;

值越大,区分度越高。

出道面试题,下面这条SQL该怎么创建联合索引:

select a from table_name where b=1 order by c;

SQL中用到abc三个字段,创建联合索引的顺序是(b,c,a)

这道题还涉及到另一个知识点,SQL执行的顺序:

from > on > join > where > group by > having > select > distinct > order by > limit

7. 注意避免深分页

MySQL深分页的时候,查询性能较差。

select * from user where name='一灯' limit 10000,10;

我们可以采用子查询的方式进行优化:

select * from user
where id in (
select id from user
where name='一灯'
limit 10000,10
);

这样可以减少非聚簇索引回表查询的次数。

8. 单表字段不要超过30个

当单表字段数量过多的时候,加载大量数据也会拖慢查询性能。

如果字段超过30个,不用看,肯定是表设计的不合理。

这时候,可以拆成多张表,用垂直分表的方式,进行冷热字段分离。

9. 枚举字段不要使用字符类型

字符类型会占用更多的存储空间,当我们想要存储枚举值或者表示是否的时候,可以采用tinyint数值类型,最好采用无符号整数unsigned tinyint

10. 小数类型禁止使用float和double

在存储和计算的时候,floatdouble 都存在精度损失的问题,无法得到正确的结果。

所以在涉及到存储小数的时候,必须使用decimal类型。

11. 所有字段必须设置默认值且不允许为null

字段允许为null,会占用额外的存储空间。

索引并不会索引null值,所以查询null值的时候无法用到索引。

当数值类型允许为null,返回给映射实体类的时候还可能会报空指针异常。

12. 必须创建主键,最好是有序数值类型

如果我们自己没有给表设置主键,InnoDB会自动增加一列隐藏的主键,我们无法使用到,并且也占用的更多的存储空间,所以建表的时候,必须设置主键。

有序数值更适合做主键,插入数据的时候,由于是有序的,不会频繁调整B+树结构,性能更好。

13. 快速判断是否存在某条记录

一般我们判断表中是否存在某条记录的时候,会使用count函数,然后判断返回值是否大于1。

select count(*) from user where name='一灯';

InnoDB存储引擎并没有像MyIsAm那样缓存表的总行数,每次查询都是实时计算的,耗时较长。

我们可以采用limit加快查询效率:

select id from user where name='一灯' limit 1;

limit 1表示匹配到一条就返回,查询效率更好,结果集只返回id,还可以用到覆盖索引。

14. in条件中数量不宜过多

in条件中数量不要超过1000个,不然耗时会非常长,可以拆成多批次查询。

15. 禁止创建预留字段

无法通过预留字段的名称判断这个字段是干嘛用的。

预留字段的类型不一定合适。

无法为预留字段创建合适的索引。

16. 单表索引数不要超过5个

创建适当的索引可以提高查询效率,但是过多的索引,不但占用更多存储空间,还会拖慢更新SQL的性能。

所以,索引好用,适度即可。

知识点总结:

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

精心整理16条MySQL使用规范,减少80%问题,推荐分享给团队的更多相关文章

  1. Spring Boot 最流行的 16 条实践解读!【华为云技术分享】

    置顶:华为云618大促火热进行中,全场1折起,免费抽主机,消费满额送P30 Pro,点此抢购. Spring Boot是最流行的用于开发微服务的Java框架.在本文中,将与大家分享自2016年以来笔者 ...

  2. [转载] 根据多年经验整理的《互联网MySQL开发规范》

    原文: http://weibo.com/p/2304181380b3f180102vsg5 根据多年经验整理的<互联网MySQL开发规范> 写在前面:无规矩不成方圆.对于刚加入互联网的朋 ...

  3. 根据多年经验整理的《互联网MySQL开发规范》

    一.基础规范 使用 INNODB 存储引擎 表字符集使用 UTF8  所有表都需要添加注释 单表数据量建议控制在 5000W 以内 不在数据库中存储图⽚.文件等大数据 禁止在线上做数据库压力测试 禁⽌ ...

  4. 30多条mysql数据库优化方法,千万级数据库记录查询轻松解决(转载)

    1.对查询进行优化,应尽量避免全表扫描,首先应考虑在 where 及 order by 涉及的列上建立索引. 2.应尽量避免在 where 子句中对字段进行 null 值判断,否则将导致引擎放弃使用索 ...

  5. 30多条mysql数据库优化方法【转】

    1.对查询进行优化,应尽量避免全表扫描,首先应考虑在 where 及 order by 涉及的列上建立索引. 2.应尽量避免在 where 子句中对字段进行 null 值判断,否则将导致引擎放弃使用索 ...

  6. 19条MySQL优化准则

    1.EXPLAIN 做MySQL优化,我们要善用EXPLAIN查看SQL执行计划. 下面来个简单的示例,标注(1.2.3.4.5)我们要重点关注的数据: type列,连接类型.一个好的SQL语句至少要 ...

  7. 巧用这19条MySQL优化【转】

    1.EXPLAIN 做MySQL优化,我们要善用EXPLAIN查看SQL执行计划. 下面来个简单的示例,标注(1.2.3.4.5)我们要重点关注的数据: type列,连接类型.一个好的SQL语句至少要 ...

  8. Git使用方法(精心整理,绝对够用)转载

    Git使用方法(精心整理,绝对够用)   一.git客户端(本地仓库)的一些操作 1.设置账户(需要和github账户设置一致) git config --global user.name xxx g ...

  9. 转载:30多条mysql数据库优化方法,千万级数据库记录查询轻松解决

    1.对查询进行优化,应尽量避免全表扫描,首先应考虑在 where 及 order by 涉及的列上建立索引. 2.应尽量避免在 where 子句中对字段进行 null 值判断,否则将导致引擎放弃使用索 ...

随机推荐

  1. 846. Hand of Straights - LeetCode

    Question 846. Hand of Straights Solution 题目大意:打牌,判断牌是否能全部按顺子出 思路:构造一个list,存储1,2,3,4,5,6,7,8并排序,构造一个m ...

  2. Fail2ban 命令详解 fail2ban-regex

    fail2ban-regex是fail2ban提供的用来测试正则表达式的一个小工具,我们可以用它来测试正则表达式是否能够匹配到日志文件中的要禁止的IP行. fail2ban-regex默认情况下自动匹 ...

  3. 第06组Alpha冲刺(3/6)

    目录 1.1 基本情况 1.2 冲刺概况汇报 1.郝雷明 2.鲍凌函 3.曾丽莉 4. 曹兰英 5. 方梓涵 6.董翔云 7.杜筱 8.黄少丹 9. 詹鑫冰 10.吴沅静 1.3 冲刺成果展示 1.1 ...

  4. 《Unix 网络编程》11:名字和地址转换

    名字和地址转换 系列文章导航:<Unix 网络编程>笔记 域名系统 简介 域名系统主要用于主机名字和 IP 地址之间的映射.主机名可以是: 简单名字,如:centos01 全限定域名(FQ ...

  5. Lucene从入门到实战

    Lucene 在了解Lucene之前,我们先了解下全文数据查询. 全文数据查询 我们的数据一般分为两种:结构化数据和非结构化数据 结构化数据:有固定格式或有限长度的数据,如数据库中的数据.元数据 非结 ...

  6. 3D大场景展示功能你了解多少?见详解!

    裸眼3D技术的出现打破了真实与虚拟的界限,人们不仅希望能够体验奇妙的虚拟场景,也希望足不出户在短短几分钟内就能看到遍布各地的场景,希望能实时对接关键数据. 裸眼3D技术的出现打破了真实与虚拟的界限,人 ...

  7. sap 获取设置的打印机参数

    *&---------------------------------------------------------------------* *& Form FRM_SET_PRI ...

  8. 《HelloGitHub》第 75 期

    兴趣是最好的老师,HelloGitHub 让你对编程感兴趣! 简介 HelloGitHub 分享 GitHub 上有趣.入门级的开源项目. https://github.com/521xueweiha ...

  9. java基础知识面试总结-部分

    前言 在平时的工作学习中,自己对微服务和springboot基础理论知识关注比较少,在面试中对于面试官的问题,很多基本都不能够达到精准,全面:现将自己面试中的问题做以总结: 1.谈谈你对微服务架构的认 ...

  10. 所有人都说Python 简单易学,为何我觉得难?

    来谈谈心 记得刚学Python的时候,几乎所有人都说Python 简单易学,而对于编程零基础,只掌握Word和Excel的人来说,感觉真的好难. 学习之前网上的教材看了,Python的书也看了,包括& ...