Introduction to SQL Tuning
- SQL效率太低的原因:
- Stale or missing optimizer statistics:缺失优化统计信息或者信息太旧;
- Missing access structures:缺少索引,考虑索引的效率;
- Suboptimal execution plan selection:不是最好的执行计划;
- Poorly constructed SQL:SQL语句写的不好;
- 最重要的是表的数据量太大,归档历史数据.小的数据量可以解决一切问题;
- 解决办法:
- 尽量不要用子查询,可以通过关联查询解决;
- 不要再表列上面使用函数,导致索引无效;
- 如果发生隐式转换也不走索引,因为oracle内部总是转换表的列;
- 尽量使用UNION ALL而不用UNION;
- 排序,去重复,分组现在默认使用hash去除重复,对CPU消耗很大;
- 性能监控的解决方案;
- Oracle中监控和调优的工具;
- 调优的工具:
- Automatic Database Diagnostic Monitor (ADDM);
- SQL Tuning Advisor;
- SQL Tuning Sets;
- SQL Access Advisor;
- SQL Performance Analyzer;
- SQL Monitoring;
- SQL Plan Management:在11g中的工具,可以控制某个sql的执行计划;
- SQL调优的任务:
- 查找高负载的SQL语句;
- 收集统计信息;
- 收集系统统计信息;
- 重建已存在的索引;
- 维护执行计划;
- 创建新的索引;
- CPU和Wait Time的调优
- db_time=cpu_time+wait_time;
- 如果db_time增加,cpu_time和wait_time等比例增加,说明这是一个可扩展的系统,只需增加硬件即可;
- 如果db_time增加,cpu_time远大于wait_time的增加,说明SQL效率不高,需要SQL的优化;
- 如果db_time增加,cpu_time远小于wait_time的增加,说明内部有争用或者IO效率太低;
- 客户系统的常见问题:
- Bad connection management:可以使用连接池解决;
- Bad use of cursors and the shared pool:适当调大SGA和PGA,并指定动态管理;
- Excess of resources consuming SQL statements:sql要反复执行;
- Use of nonstandard initialization parameters:使用了隐含参数或者参数使用不当;
- Poor database disk configuration:IO问题;
- Redo log setup problems:至少使用三组在线日志组,每组设置足够大,保证20分钟切换一次;
- Excessive serialization:串行化扫描,添加索引,尽量使用单列索引,可控性比较强;
- Inappropriate full table scans:全表扫描,主要是加索引解决;
- Large number of space-management or parse-related generated SQL statements:如果使用本地管理表空间的的话一般不会出现递归SQL;
- Deployment and migration errors:部署时出错,这个是人为原因;
- 应用的设计:
- 简化设计;
- 数据模型:
- 主要还是要与业务逻辑相结合;
- 可以使用建模工具如Oracle Designer,但是最好是使用详细的文档;
- 考虑是OLTP系统还是DW系统;
- 表设计:
- 考虑使用默认值,约束,物化视图,分区表等特性;
- 分区列一定要在where条件上,而且最好不要更新;
- 不建议使用触发器;,触发器的目的是做check,而不是做DML;
- 不建议使用外键,可以使用程序保证数据的完整性;
- 索引设计:
- 索引的列一定要经常出现在WHERE后面;
- 在DW中建议使用外键,在OLTP中考虑到性能可以不用外键,加外键的话就一定要加索引;
- 视图:
- 可以使用视图,但是最好不要嵌套视图;
- 嵌套视图影响执行计划;
- Share Cursors
- 尽量使用存储过程和函数;
- cursor_sharing初始化参数尽量不要修改;