#SQL级调优
典型的SQL调优涉及以下步骤:
识别高负载的SQL语句。
用户可以从性能视图、性能报告或日志中,找到耗时多、占用系统资源多的语句。
收集与性能相关数据,包括统计信息和元数据:
统计信息:优化器统计信息记录了表数据规模和分布等信息,统计信息至关重要,如果统计信息不存在或过时,优化器将无法生成最佳计划。
元数据:收集SQL需要访问的表和视图的结构,以及该语句可能用到的索引定义。
确定问题的原因,常见原因包括:
执行效率低下的SQL
如果编写的SQL执行了不必要的操作,那么优化器将无法提升其性能,例如:没有连接条件的连接语句(笛卡尔积)、指定大表做驱动表、指定UNION而不是UNION ALL、使用子查询针对外部查询中的每一行执行等。
执行计划不是最优
优化器会在所有可能的执行路径选择理论上最优的计划,但不意味着优化器一定能选出最优计划。有时,优化器会选择一个访问路径不理想的计划,例如,使用低选择率的谓词条件,可能会在大表上使用全表扫描而不是索引。
数据访问结构不合理
缺少索引和视图未物化是导致SQL性能欠佳的典型原因。最佳的访问结构能够对SQL性能进行指数级的提升。
过时的优化器统计信息
当统计信息维护操作(自动或手动)无法跟上DML导致的表数据更改时,收集到的统计信息可能会过时。由于表上的陈旧统计信息无法准确反映表数据分布,因此优化程序可能会基于错误信息做出决策并生成较差的执行计划。
不合理的数据库系统参数
经过数据库初始化配置调优后的参数在大多数情况下是能够满足用户需要的,但随着环境和数据规模的变化,应适时对配置参数进行合理的调整。例如SGA的大小影响内存的分配,如果过小将影响到缓存的命中率,增大IO负担,从而影响性能。
硬件问题
性能问题同样跟CPU、内存和IO有关,对系统资源的配置进行优化将可以提升所有SQL的性能。
定义问题的范围。
问题解决方式的范围必须与问题的范围相匹配,用户需要判断问题的范围是在实例级别还是SQL语句级别。例如,shared pool太小会引起计划缓存被淘汰,进而导致很多硬解析,此时通过调整配置参数增加shared pool的大小可以解决实例级别的问题,并提高所有会话的性能。但是,如果因为某条SQL语句没能使用有效的索引,而更改整个数据库的优化器相关配置参数,可能会损害整体性能。因此,当单个SQL语句有问题时,应该使用属于语句级别的解决方案处理问题。
优化执行性能。
下列操作均可以有效地提升SQL执行效率,用户可以根据自身情况使用一种或多种:
重写SQL以提高效率
使用绑定变量减少硬解析
使用等值的连接条件
过滤条件中不使用函数
将复杂SQL分解为多个简单语句和使用并行等。
此外,可以通过改变元数据对象来提升性能,例如增加索引、调整索引顺序、使用分区表甚至调整数据设计等。
防止SQL性能下降。
定期查看性能报告或日志,尽可能保证优化器产生的计划一直最优。
关于SQL级的详细调优指导请参考SQL调优章节介绍。