Subquery Factoring, 其实就是平常比较熟悉的With语句,Adrian Billington 在他的网站上写了一篇介绍Subquery Factoring很好的文章,见这里。这篇Blog同样是对他的这篇文章的笔记。
With语句一般有两种用途,一种就是用来把复杂的SQL语句简单化:复杂的SQL语句一般都会嵌套很多层次,无论是写起来还是读起来都很困难,通过用With语句,把子查询语句抽取出来,这样可以使得SQL语句“扁平化”,写起来会很方便,读起来也很容易。 With的这种用法其实就是相当于把复杂语句中的inline-view给提取出来作为一个单独的查询语句,并赋予一个名字,这样用起来就跟访问一个视图一样。
With的另外一种用处是可以用来优化SQL语句,如果一个复杂的SQL语句需要重复访问一张表(最好是数据量比较大的表),这个时候如果用With把这部分需要重复访问底层表的SQL语句提取出来(Oracle往往会把这部分数据“物化”到一个临时表中),之后就不用重复多次访问底层表,从而可以提升SQL语句的执行效率。
下面主要看看With在SQL优化方面的一个例子,(注意, 我得到的结果跟Adrian很不一样, 我用的是10g来run他的例子的!)
首先创建测试用例:
SQL> show user
USER is "FRANK"
SQL> CREATE TABLE sales
2 NOLOGGING
3 AS
4 SELECT al.owner AS region
5 , al.object_type AS product
6 , al.object_id AS order_amt
7 FROM all_objects al
8 , all_objects a2
9 WHERE ROWNUM <= 1000000;
Table created.
SQL> exec DBMS_STATS.GATHER_TABLE_STATS(USER, 'sales');
PL/SQL procedure successfully completed.