【SQL 必知必会】 性能篇 01. 如何考虑数据库调优
1. 数据库调优的对象与目标
对象:整个DBMS,包括 SQL查询,数据库部署配置,架构等
目标:数据库响应时间快,吞吐量更大。
2. 调优考虑的维度有哪些
用户反馈:是最及时的,是最直接的。
日志分析:通过数据库日志以及操作系统日志定位问题。
服务器资源使用监控:监控服务器的cpu、内存、I/O等使用情况,实时了解服务器性能使用,与历史情况对比。
数据库内部情况监控:活动会话(Active Session)监控是一个重要的指标。通过它,你可以清楚地了解数据库当前是否处于非常繁忙的状态,是否存在 SQL 堆积等 事务,锁等待进行监控。
2.1 第一步,根据业务选择适合的DBMS
此时你需要了解不同类型的数据库的优缺点以及使用场景,例如常用的SQL Server 、Oracle、 MySQL,这些数据库在查询性能以及事务处理都很高。
非关系型数据库不同的数据库有不同的数据场景,比如列式存储数据库可以大幅度降低系统的 I/O,适合于分布式文件系统和 OLAP,但如果数据需要频繁地增删改,那么列式存储就不太适用了。
2.2 第二步,优化表的设计
- 表结构尽量遵从三范式,减少冗余字段,可以减少增删改查数据时异常情况发生。
- 如果查询多,例如多表联查的情况,用反范式,牺牲空间换时间,增加冗余字段,提高查询效率。
- 表字段数据类型选择要合理,查询效率的高低以及存储空间的大小和表字段类型有很大关系,能采用数值类型尽量不采用字符串类型,即使采用字符串类型,字符串的长度尽量设计的短一些。 确定字符串长度固定时,可采用CHAR类型;长度不固定采用VACHAR类型。
2.3 第三步,优化逻辑查询:重写SQL语句
SQL查询分为逻辑查询和物理查询。
SQL 的查询重写包括了子查询优化、等价谓词重写、视图重写、条件简化、连接消除和嵌套连接消除等
比如 exists 和 in 的子查询会根据小表驱动大表的原则选择合适的子查询。 以及WHERE 子句中尽量避免对字段进行函数运算,它会让字段的索引失效。
2.4 优化物理查询:在逻辑查询基础之上,高效的建立索引
索引不是万能的,需要根据实际情况创建索引,那么都有哪些情况呢?
数据重复度高,就不需要创建索引。通常在重复度超过 10% 的情况下,可以不创建这个字段的索引。比如性别这个字段(取值为男和女)。
索引列的位置对索引使用的影响。比如我们在 WHERE 子句中对索引字段进行了表达式的计算,会造成这个字段的索引失效。
联合索引对索引的影响。在创建联合索引的时候会对多个字段创建索引,不同的索引的顺序查询效率也不同。
索引不是越多越好。索引多了会占用更多的存储空间,也会导致优化器增加对索引的筛选时间,影响评估效率。
**物理查询优化是在确定了逻辑查询优化之后,采用物理优化技术(比如索引等),通过计算代价模型对各种可能的访问路径进行估算,从而找到执行方式中代价最小的作为执行计划。
第五步,使用Redis 或 Memcached 作为缓存
频繁的数据库查询 浪费数据库资源。此时可以将经常查询且不变的数据放入到内存当中,可提升查询效率。适用于响应时间短,吞吐量大的场景。我们可以用非关系型数据库对关系型数据库做一下互补。
Redis支持持久化,Memcached不支持持久化。
第六步,库级优化:站在数据库的维度上进行的优化
-
控制一个库中的数据表数量。另外我们可以采用主从架构优化我们的读写策略。对数据库进行读写分离,主数据库(master)完成写的操作 ,从数据库(slave)完成读的操作。
-
对数据表进行分库分表。将一个数据库切成多份,放在多台服务器上,实现负载均衡。
-
Mysql 数据库自带分区表功能,当然可以考虑做垂直切分和水平切分。
-
数据库中的数据表过多,采用垂直分库: 将关联的数据表部署在一个数据库上。
-
数据表的列过多,采用垂直分表,将数据表分成多张表,经常使用过的列放在一表中。
-
数据表中数据达到了亿级以上,可以考虑水平切分,将大的数据表拆成不同的子表,每个表保持相同的数据结构。可按照年份来划分,一个年份一张表。
总结
采用垂直分表的形式,就是将一张数据表分拆成多张表,采用水平拆分的方式,就是将单张数据量大的表按照某个属性维度分成不同的小表。
无论是垂直切分还是水平切分,要考虑切分后是否真正的提高的数据库性能以及增加了哪些维护和使用成本。
3. 总结
看人家评论上写了对上述SQL 调优的维度把控,就是选择好装备,在选择好作战路线,必要时请求外援。
本篇博客是我对 陈旸老师的SQL必知必会中 当我们思考数据库调优时,都有哪些维度可以考虑。中的一篇进行的总结,来来来,动动你的小手,点赞评论分享心得走一波。