说到SQL调优,那可以说是开发者日常开发过程中经常会遇到的问题,不管你使用的是开源Mysql数据库,还是云原生数据库,或者是其他数据库,SQL调优的问题都是一个长期且久远的事。由于最近的项目使用的是DM数据库,那么这里就基于DM数据库SQL调优来浅谈一下吧。
SQL 调优
SQL 调优作为数据库性能调优中的最后一个环节,对查询性能产生着直接的影响。SQL 调优的整体目标简单的说就是使用最优的执行计划,这意味着 IO 以及 CPU 代价最小,来达到最大的查询性能。
SQL调优方案
对于SQL调优,常见的方案有优化SQL,增加索引,优化表结构等,这里主要讲述一下日常写SQL过程中可能会忽略的SQL调优细节。
避免OR子句
大家都知道,通常情况下一个 OR 子句不能利用上索引则会使用全表扫描造成效率低下,所以应尽量避免使用OR子句,但是有时候可能不得不用OR子句,这个时候可以用以下替代方案。分析OR子句,通常是针对一列进行过滤,那么可以使用IN,比如
select*from edu_face_train_apply_person where person_id=7or person_id=8;
改写成
select*from edu_face_train_apply_person where person_id in(7,8);
SELECT 项避免‘*’
通常情况下,SQL查询往往并不需要得到表中所有列,那么此时使用SELECT *这种写法将让执行器背上沉重的负荷。因为每一列的数据不得不自下往上层层向上传递,这样对于磁盘IO的损耗是巨大的。这个时候就需要开发者了解表结构和业务需求,小心地选择需要的列并一一给出名称,避免直接用 SELECT *。这样可以尽可能的提高查询效率。
避免重复索引
可以说数据库添加索引在一定程度上可以提高数据库SQL的查询效率,但是并不是说索引就建的越多越好,大量重复的索引并不利于提高查询效率的同时,如果表的增删改操作频繁,那么对于索引的维护同样也是耗时巨大的,因此索引的创建要适宜。
COUNT(*)统计行数
使用COUNT(*)统计行数,如果没有过滤条件,DM 优化器会直接读取相关索引中存储的行数信息并进行内部修正后,迅速地给出最终结果而避免对实际数据的读取。而COUNT(列名)会对数据进行读操作,执行效率远低于 COUNT(*)。在有过滤条件时,COUNT(*)执行效率依然优于其他。另外,COUNT(*)会将 NULL 值计算在内而 COUNT(列名)是不包含 NULL 值的,因此需要注意应用场景决定是否可以使用 COUNT(*)。
UNION 和 UNION ALL
UNION 和 UNIONALL 的区别是前者会过滤掉值完全相同的数据,因此如果应用场景并不关心重复数据或者不可能出现重复,那么 UNION ALL 无疑优于 UNION。
当然除了以上这些SQL优化的方案,比如SQL查询中减少表关联等同样可以提高查询效率。
最后
关于达梦数据库更多查询优化方案以及提高查询效率相关分析说明可以参考达梦数据库官方文档:查询优化