MySQL索引&&开发规范
规范总结
索引规范
默认添加的索引都是BTree索引。Innodb只支持BTree索引。
设计索引原则
- 最适合索引的列是WHERE子句中的列,而不是SELECT中的列。
- 如果索引的字段很长,使用前缀索引
- 删除不常用索引
- 建议单表不超过5个
单表索引不超过5个【索引可以提高查询效率,但是会减小插更新效率】
每个 Innodb 表必须有个主键,【主键建议使用自增 ID 值】
索引列建议
- 出现在 SELECT、UPDATE、DELETE 语句的 WHERE 从句中的列
- 包含在 ORDER BY、GROUP BY、DISTINCT 中的字段
- 并不要将符合 1 和 2 中的字段的列都建立一个索引, 通常将 1、2 中的字段建立联合索引效果更好
- 多表 join 的关联列
避免建立冗余索引和重复索引
- 重复索引示例:primary key(id)、index(id)、unique index(id)
- 冗余索引示例:index(a,b,c)、index(a,b)、index(a)
覆盖索引
to be continue
外键约束取舍
开发规范
禁止使用 SELECT * 必须使用 SELECT 查询
用join操作代替子查询
使用join关联的表最好不超过5个
对应同一列进行 or 判断时,使用 in 代替 or
禁止使用 order by rand() 进行随机排序
【推荐在程序中获取一个随机值,然后从数据库中获取数据的方式。】
WHERE 从句中禁止对列进行函数转换和计算
【对列进行函数转换或计算时会导致无法使用索引】
在明显不会有重复值时使用 UNION ALL 而不是 UNION
- UNION 会把两个结果集的所有数据放到临时表中后再进行去重操作
- UNION ALL 不会再对结果集进行去重操作
拆分复杂的大 SQL 为多个小 SQL
- 大 SQL 逻辑上比较复杂,需要占用大量 CPU 进行计算的 SQL
- MySQL 中,一个 SQL 只能使用一个 CPU 进行计算
- SQL 拆分后可以通过并行执行来提高处理效率
索引设计规范
1. 限制每张表上的索引数量,建议单张表索引不超过 5 个
索引并不是越多越好!索引可以提高效率同样可以降低效率。
索引可以增加查询效率,但同样也会降低插入和更新的效率,甚至有些情况下会降低查询效率。
因为 MySQL 优化器在选择如何优化查询时,会根据统一信息,对每一个可以用到的索引来进行评估,以生成出一个最好的执行计划,如果同时有很多个索引都可以用于查询,就会增加 MySQL 优化器生成执行计划的时间,同样会降低查询性能。
2. 每个 Innodb 表必须有个主键
Innodb 是一种索引组织表:数据的存储的逻辑顺序和索引的顺序是相同的。每个表都可以有多个索引,但是表的存储顺序只能有一种。
Innodb 是按照主键索引的顺序来组织表的
- 不要使用更新频繁的列作为主键,不适用多列主键(相当于联合索引)
- 不要使用 UUID,MD5,HASH,字符串列作为主键(无法保证数据的顺序增长)
- 【主键建议使用自增 ID 值】
- 常见索引列建议
- 出现在 SELECT、UPDATE、DELETE 语句的 WHERE 从句中的列
- 包含在 ORDER BY、GROUP BY、DISTINCT 中的字段
- 并不要将符合 1 和 2 中的字段的列都建立一个索引, 通常将 1、2 中的字段建立联合索引效果更好
- 多表 join 的关联列
- 避免建立冗余索引和重复索引(增加了查询优化器生成执行计划的时间)
- 重复索引示例:primary key(id)、index(id)、unique index(id)
- 冗余索引示例:index(a,b,c)、index(a,b)、index(a)
- 对于频繁的查询优先考虑使用覆盖索引
覆盖索引:就是包含了所有查询字段 (where,select,ordery by,group by 包含的字段) 的索引
覆盖索引的好处:
- 避免 Innodb 表进行索引的二次查询: Innodb 是以聚集索引的顺序来存储的,对于 Innodb 来说,二级索引在叶子节点中所保存的是行的主键信息,如果是用二级索引查询数据的话,在查找到相应的键值后,还要通过主键进行二次查询才能获取我们真实所需要的数据。而在覆盖索引中,二级索引的键值中可以获取所有的数据,避免了对主键的二次查询 ,减少了 IO 操作,提升了查询效率。
- 可以把随机 IO 变成顺序 IO 加快查询效率: 由于覆盖索引是按键值的顺序存储的,对于 IO 密集型的范围查找来说,对比随机从磁盘读取每一行的数据 IO 要少的多,因此利用覆盖索引在访问时也可以把磁盘的随机读取的 IO 转变成索引查找的顺序 IO。
6.索引 SET 规范
尽量避免使用外键约束
- 不建议使用外键约束(foreign key),但一定要在表与表之间的关联键上建立索引
- 外键可用于保证数据的参照完整性,但建议在业务端实现
- 外键会影响父表和子表的写操作从而降低性能
数据库 SQL 开发规范
- 禁止使用 SELECT * 必须使用 SELECT 查询
原因:
- 消耗更多的 CPU 和 IO 以网络带宽资源
- 无法使用覆盖索引
- 可减少表结构变更带来的影响
- 避免使用子查询,可以把子查询优化为 join 操作
通常子查询在 in 子句中,且子查询中为简单 SQL(不包含 union、group by、order by、limit 从句) 时,才可以把子查询转化为关联查询进行优化。
子查询性能差的原因:
子查询的结果集无法使用索引,通常子查询的结果集会被存储到临时表中,不论是内存临时表还是磁盘临时表都不会存在索引,所以查询性能会受到一定的影响。特别是对于返回结果集比较大的子查询,其对查询性能的影响也就越大。
由于子查询会产生大量的临时表也没有索引,所以会消耗过多的 CPU 和 IO 资源,产生大量的慢查询。
- 避免使用 JOIN 关联太多的表
对于 MySQL 来说,是存在关联缓存的,缓存的大小可以由 join_buffer_size 参数进行设置。
在 MySQL 中,对于同一个 SQL 多关联(join)一个表,就会多分配一个关联缓存,如果在一个 SQL 中关联的表越多,所占用的内存也就越大。
如果程序中大量的使用了多表关联的操作,同时 join_buffer_size 设置的也不合理的情况下,就容易造成服务器内存溢出的情况,就会影响到服务器数据库性能的稳定性。
同时对于关联操作来说,会产生临时表操作,影响查询效率,MySQL 最多允许关联 61 个表,建议不超过 5 个。
- 对应同一列进行 or 判断时,使用 in 代替 or
in 的值不要超过 500 个,in 操作可以更有效的利用索引,or 大多数情况下很少能利用到索引。
- 禁止使用 order by rand() 进行随机排序
order by rand() 会把表中所有符合条件的数据装载到内存中,然后在内存中对所有数据根据随机生成的值进行排序,并且可能会对每一行都生成一个随机值,如果满足条件的数据集非常大,就会消耗大量的 CPU 和 IO 及内存资源。
推荐在程序中获取一个随机值,然后从数据库中获取数据的方式。
- WHERE 从句中禁止对列进行函数转换和计算
对列进行函数转换或计算时会导致无法使用索引
不推荐:
where date(create_time)='20190101'
推荐:
where create_time >= '20190101' and create_time < '20190102'
- 在明显不会有重复值时使用 UNION ALL 而不是 UNION
- UNION 会把两个结果集的所有数据放到临时表中后再进行去重操作
- UNION ALL 不会再对结果集进行去重操作
- 拆分复杂的大 SQL 为多个小 SQL
- 大 SQL 逻辑上比较复杂,需要占用大量 CPU 进行计算的 SQL
- MySQL 中,一个 SQL 只能使用一个 CPU 进行计算
- SQL 拆分后可以通过并行执行来提高处理效率
参考资料
一份非常完整的MySQL规范
https://baijiahao.baidu.com/s?id=1622786252178335118&wfr=spider&for=pc
MySQL索引&&开发规范的更多相关文章
- MySQL数据库开发规范知识点
前言: 设计规范更多的是为了确保数据库设计的合理性.为了项目最终的协调稳定性,而命名规范则更多的是为了确保设计的正式和统一. 约定优先于配置(Convention Over Configuration ...
- MySQL之开发规范
一..数据库命名规范 1.所有数据库对象名称必须使用小写字母并用下划线分割 2.所有数据库对象名称禁止使用mysql保留关键字(如果表名中包含关键字查询时,需要将其用单引号括起来) 3.数据库对象的命 ...
- MySQL数据库开发规范-EC
最近一段时间一边在线上抓取SQL来优化,一边在整理这个开发规范,尽量减少新的问题SQL进入生产库.今天也是对公司的开发做了一次培训,PPT就不放上来了,里面有十来个生产SQL的案例.因为规范大部分还是 ...
- 【转】拍拍网2015年mysql最新开发规范
1.命名规范 (1)库名.表名.字段名必须使用小写字母,并采用下划线分割. (2)库名.表名.字段名禁止超过32个字符. (3)库名.表名.字段名必须见名知意.命名与业务.产品线等相关联. (4)库名 ...
- mysql数据库开发规范
对规范的遵守可用二八原则,不要教条.为满足实际需求 可忽视部分规范. 1.索引规范 *目标 |--利用最小的索引成本找到需要的行记录 *原则 |--做前缀匹配 |--选择区分度高的列做前缀索引列 |- ...
- Mysql 数据库开发规范
设计范式参看,DDL与DDL 库表基础规范 1.注释 每个表要添加注释,对 status 型需指明主要值的含义,如”0-离线,1-在线” 2.表的字段数量 单表字段数一般考虑上限为 30左右,再多的话 ...
- 从MySQL开发规范处看创业
版权声明:本文为博主原创文章.未经博主同意不得转载. https://blog.csdn.net/n88Lpo/article/details/78099185 作者:唐勇.深圳市环球易购.MySQL ...
- MySQL架构设计谈:从开发规范、选型、拆分到减压(转)
作者介绍 李辉,原新浪爱彩票运维负责人,常用网名:门牙没了.曾主导新浪爱彩票的MySQL运维工作.培训合伙人.资深讲师,中国科学院大学在读研究生(大数据方向),擅长大型项目的关系型数据库运维和管理,现 ...
- [转载] 根据多年经验整理的《互联网MySQL开发规范》
原文: http://weibo.com/p/2304181380b3f180102vsg5 根据多年经验整理的<互联网MySQL开发规范> 写在前面:无规矩不成方圆.对于刚加入互联网的朋 ...
随机推荐
- warpAffine仿射变换
仿射变换,其实就是不同的坐标系的相互转换,用于图像的平移和旋转. 首先看一下官方的api描述. https://docs.opencv.org/2.4/modules/imgproc/doc/geom ...
- Redis 学习笔记(篇九):主从复制
Redis 中,可以通过执行 savleof 命令或者设置 slaveof 选项,让一个服务器去复制另一个服务器,我们称被复制的服务器为主服务器,而对主服务器进行复制的服务器则被称为从服务器. Red ...
- @Validated和@Valid区别
注解地方 @Validated:可以用在类型.方法和方法参数上.但是不能用在成员属性(字段)上 @Valid:可以用在方法.构造函数.方法参数和成员属性(字段)上 两者是否能用于成员属性(字段)上直接 ...
- python多进程通信实例分析
操作系统会为每一个创建的进程分配一个独立的地址空间,不同进程的地址空间是完全隔离的,因此如果不加其他的措施,他们完全感觉不到彼此的存在.那么进程之间怎么进行通信?他们之间的关联是怎样的?实现原理是什么 ...
- 12 redis搭建主从服务(ubuntu)
什么是主从服务 一个master可以拥有多个slave,一个slave可以拥有多个slave,如此下去,形成了多级服务器集群架构 master用来写数据, slave用来读数据, 经统计:网站的读写比 ...
- C#开发学习人工智能的第一步
前言 作为一个软件开发者,我们除了要学会复制,黏贴,还要学会调用API和优秀的开源类库. 也许,有人说C#做不了人工智能,如果你相信了,那只能说明你的思想还是狭隘的. 做不了人工智能的不是C#这种语言 ...
- RestTemplate 1
@Inject private RestTemplate restTemplate; @SuppressWarnings("unchecked") public Use ...
- Windows 7 sometimes breaks FTP connections on Java 7 if firewall is enabled.
Solution: 用管理员身份,在cmd命令行输入: netsh advfirewall set global StatefulFTP disable 会关闭防火墙,从而解决问题.
- POJ-2018 Best Cow Fences 二分
题意:找到一个连续区间,区间的长度至少大于f,现在要求这个区间的平均值最大. 题解: 二分找答案. 每次对于2分的mid值, 都把原来的区间减去mid, 然后找到一长度至少为f的区间, 他们的区间和& ...
- Codeforces 938D Buy a Ticket
Buy a Ticket 题意要求:求出每个城市看演出的最小费用, 注意的一点就是车票要来回的. 题解:dijkstra 生成优先队列的时候直接将在本地城市看演出的费用放入队列里, 然后直接跑就好了, ...