高级SQL优化(一)
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
高级SQL优化(一)
SQL优化简介
一般在应用中,糟糕的SQL语句是造成系统性能低下的最主要原因,例如大小写的不统一、同样的SQL语句不同的写法等。而且,随着数据量的增加,情况会变得越来越严重。(题外话:优秀的Oracle数据库优化人才,是任何公司都稀缺的)
SQL优化又称SQL调节,其步骤一般包括:
SQL调节的目标
SQL调节包括三大目标:降低负载、均衡负载和并行化负载。
l降低负载:即寻找更高效的途径来完成相同的功能
如某个非大表(小于2000万行数据数据或小于2G大小的单表),常规查询需要访问的数据实践中90%情况下是不会超过20%的,此时建立合理的索引是有效的方法之一
l均衡负载:即应该把任务分时段均衡调度
如一般系统白天是访问高峰,如果此时备份任务、批处理任务或报表数据抽取任务也挤在这个时段则易
造成负载峰
值现象,正确的做法应该是把备份任务、批处理任务和报表数据抽取任务放到晚上进行处理,或采用并行化策略
l并行化负载:即大数据量的查询访问需要使用并发策略
如在数据仓库环境中应该多使用并发策略,此举可以明显减少响应时间
SQL优化阶段
使用OEM发现顶级SQL
在OEM中,选择性能->其它监视链接->定级活动,如下图:
不要用*代替所有列名
指定仅仅需要的列名与使用*对比:
时间:359/1327=27.05% CUP耗费: 4092121327/6413227637=63.81%
IO耗费: 29601/110117=26.88% 可见大幅降低I/O从而降低响应时间!
SQL优化技巧
使用TRUNCATE代替DELETE
Oralce执行DELETE后会使用UNDO表空间存放被删除的信息以便恢复,如果之后用户使用ROLLBACK而不是COMMIT,则Oralce将利用该UNDO表空间中的数据进行恢复。当使用TRUNCATE时,Oracle不会将删除的数据放入UNDO表空间,因而速度要快很多。当要删除某个表中的全部数据时,应该使用TRUNCATE而不是不带WHERE条件的DELETE。语法如下:
TRUNCATE TABLE table_name [DROP|REUSE STORAGE]
DROP STORAGE为默认的方式,表示收回被删除的表空间
REUSER STORAGE表示保留被删除的空间以供该表的新数据使用
应用开发中,可以编写一个子程序让其动态的清除空表,以供调用。
默认PCTFREE为10,假定为5,high-water mark是一个存储段分配多少存储器的标记。
活用COMMIT
PL/SQL块中,经常将几个相互联系的DML语句写在BEGIN …END,如果不影响事务的完整性,则建议在每个END前面写一个COMMIT,以达到对DML的及时提交和释放事务所占的资源的目的。
COMMIT释放的资源包括:
lUNDO段上用于恢复数据的信息
l事物中DML语句获得的锁
lSGA中重做日志缓冲区中的空间
lOracle为管理相关资源(如上述资源) 而开销的内部资源
体验例子流程如下:
体验例子显示:
减少表的查询次数
1.一个逻辑单元中,将能读出的列一次性读出,且尽量存放在本地变量中,应该杜绝不要用一个读一个
2.在包含子查询的SQL中,要特别注意减少对表的查询次数,在代码清晰时对于能减少查询次数的应坚决减少,举例如下:
3.执行计划如下,结论是什么?
以EXISTS代替DISTINCT
多表信息的查询时,避免在SELECT子句中使用DISTINCT. 一般可以考虑用EXISTS替换, EXISTS 使查询更为迅速,因为此时RDBMS核心模块将在子查询的条件一旦满足后,立刻返回结果。
优化前:
优化后:
使用默认值
使用默认之后的执行时间比为1.063/2.657=40.01%,快了一倍多!
可见在不含默认值,是null的列上没有使用索引,是全表扫描!而使用了默认值的列上使用了索引范围扫描!
l不能用null作索引,任何包含null值的列都将不会被包含在索引中。即使索引有多列的情况下,只要这些列中有一列含有null,该列就会从索引中排除。也就是说如果某列存在空值,即使对该列建索引也不会提高性能
l任何在where子句中使用is null或is not null的语句优化器是不允许使用索引的
l如果每列确实可能存在空值的情况,可以使用默认值的方式替代以便充分利用索引提高性能
使用DECODE函数减少处理步骤
l使用DECODE函数可以避免重复扫描相同记录或重复连接相同的表.
lDECODE函数也可以运用于GROUP BY 和ORDER BY子句中.
l上述例子有两步相似的操作,使用DECODE后节省一半时间,如果一组相似的操作越多,节省的时间则越多,计算公式为n-1,其中n为相似操作的步骤数
通配符的使用技巧
上例中已知数据%DX_ACCOUNT_TRADE%,只有以I开头的:0.031/1.891=1.639%
l当通配符出现在LIKE后面字符串的首位时,索引将不会被使用,因此在已知某字符的情况下,LIKE查询中应尽量不要把通配符写在首位
l%代表不定长的字符,_代表定长的字符,如果在确定要通配的字符长度时,应该尽量使用_,而不是%
定义并执行严格的SQL编写规范
使用Oracle共享游标的优点是:
l降低和减少Oracle对SQL的解析数量
l动态调整内存
l提高内存的使用率
风格请参照前面章节中的“建议的程序风格”
表的连接方式
FROM表顺序选择
使用基于规则的优化器(CBO)时,Oracle解析器按照从右到左的顺序处理FROM子句的