您的位置:首页 > 数据库 > Oracle

ORACLE中SQL查询优化研究

2015-11-24 15:24 411 查看
转自: http://www.cnblogs.com/HondaHsu/archive/2008/12/01/1345372.html
查询计划及主要统计数据如下:

[align=left] 执行计划:[/align]
[align=left] -----------------------------------------[/align]
[align=left] ……[/align]
[align=left] 2 1 HASH JOIN (Cost=5 Card=14 Bytes=224)[/align]
[align=left] 3 2 TABLE ACCESS (FULL) OF 'DEPT' (Cost=2 Card=4 Bytes=52)[/align]
[align=left] 4 2 TABLE ACCESS (FULL) OF 'EMP' (Cost=2 Card=14 Bytes=42)[/align]
[align=left] 主要统计数据:[/align]
[align=left] -----------------------------------------[/align]
[align=left] 305 recursive calls[/align]
[align=left] 46 consistent gets[/align]
[align=left] 创建物化视图EMP_DEPT:[/align]
[align=left] create materialized view emp_dept build immediate[/align]
[align=left] refresh on demand[/align]
[align=left] enable query rewrite[/align]
[align=left] as[/align]
[align=left] select dept.deptno,dept.dname,count(*)[/align]
[align=left] from emp,dept[/align]
[align=left] where emp.deptno=dept.deptno[/align]
[align=left] group by dept.deptno,dept.dname[/align]
[align=left] /[/align]
[align=left] 再次执行查询,执行计划及主要统计数据如下:[/align]
[align=left] 执行计划:[/align]
[align=left] -------------------------------------[/align]
[align=left] ……[/align]
[align=left] 1 0 TABLE ACCESS (FULL) OF 'EMP_DEPT' (Cost=2 Card=327 Bytes=11445)[/align]
[align=left] 主要统计数据:[/align]
[align=left] ------------------------------------[/align]
[align=left] 79 recursive calls[/align]
[align=left] 28 consistent gets[/align]
可见,在建立物化视图之前,首先执行两个表的全表扫描,然后进行HASH连接,再进行分组排序和选择操作;而建立物化视图后,CBO自动将上述复杂操作转换为对物化视图EMP_DEPT的全扫描,相关的统计数据也有了很大的改善,递归调用(RECURSIVE CALLS)由305降到79,逻辑I/O(CONSISTENT GETS)由46降为28。
[align=left]4.2.3 将频繁访问的小表读入CACHE[/align]
逻辑I/O总是快于物理I/O。如果数据库中存在被应用程序频繁访问的小表,可将这些表强行读入KEEP池,从而避免物理I/O的发生。

4.3 多表连接优化

最能体现查询复杂性的就是多表连接,多表连接操作往往要耗费大量的CPU时间和内存,因此多表连接查询性能优化往往是SQL优化的重点与难点。
[align=left]4.3.1 消除外部连接[/align]
通过消除外部连接,不仅使得到的查询更易于读取,而且性能也经常可以得到改善。一般的思路是,有以下形式的查询:
[align=left] SELECT …,OUTER_JOINED_TABLE.COLUMN[/align]
[align=left] FROM SOME_TABLE,OUTER_JOINED_TO_TABLE[/align]
[align=left] WHERE …=OUTER_JOINED_TO_TABLE(+)[/align]
[align=left] 可转换为如下形式的查询:[/align]
SELECT …,(SELECT COLUMN FROM OUTER_ JOINED_TO_TABLE WHERE …)FROM SOME_TABLE;
[align=left]4.3.2 谓词前推,优化中间结果[/align]
多表连接的性能低下多数是因为连接操作与过滤操作的次序不合理,大多数用户在编写多表连接查询时,总是先进行连接操作再应用过滤条件,这导致服务器做了太多的无用功。针对这类问题,其优化思路就是尽可能将过滤谓词前推,使不符合条件的记录提前被筛选掉,只对符合条件的少数记录进行连接处理,这样可成倍的提高SQL查询效能。
如下图所示的星形模型,现要统计最近三个月进货的商品在各种销售渠道上的销售业绩。



[align=center]图2 产品销售的星形模型[/align]
[align=left] 标准连接查询如下:[/align]
[align=left] Select a.prod_name,sum(b.sale_quant),[/align]
[align=left] sum(c.sale_quant),sum(d.sale_quant)[/align]
[align=left] From product a,tele_sale b,online_sale c,store_sale d[/align]
[align=left] Where a.prod_id=b.prod_id and a.prod_id=c.prod_id [/align]
[align=left] and a.prod_id=d.prod_id And a.order_date>sysdate-90[/align]
[align=left] Group by a.prod_id;[/align]
[align=left] 启用内嵌视图,且将条件a.order_date>sysdate-90前移,优化后代码如下:[/align]
Select a.prod_name,b.tele_sale_sum,c.online_sale_sum,d.store_sale_sum From product a,
(select sum(sal_quant) tele_sale_sum from product,tele_sale
Where product.order_date>sysdate-90 and product.prod_id =tele_sale.prod_id) b,
(select sum(sal_quant) online_sale_sum
from product,tele_sale
Where product.order_date>sysdate-90 and product.prod_id =online_sale.prod_id) c,
(select sum(sal_quant) store_sale_sum
from product,store_sale
Where product.order_date>sysdate-90 and product.prod_id =store_sale.prod_id) d,
[align=left] Where a.prod_id=b.prod_id and [/align]
[align=left] a.prod_id=c.prod_id and a.prod_id=d.prod_id;[/align]
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: