通过分析SQL语句的执行计划优化SQL(14)

ZDNet软件频道 时间:2009-11-17 作者:赛迪网 limeinan | 天新网 我要评论()
本文关键词:SQL Server Mssql SQL 数据库
假定A、B、C都是不是小表,且在A表上一个组合索引:A(a.col1,a.col2) ,注意a.col1列为索引的引导列。

例2:

假定A、B、C都是不是小表,且在A表上一个组合索引:A(a.col1,a.col2) ,注意a.col1列为索引的引导列。

考虑下面的查询:

select  A.col4 
from   A , B , C 
where  B.col3 = 10   and  A.col1 = B.col1  
and  A.col2 = C.col2  and  C.col3 = 5
Execution Plan
------------------------------------
   0      SELECT STATEMENT Optimizer=CHOOSE
   1    0  MERGE JOIN
   2    1  SORT (JOIN)
   3    2  NESTED LOOPS
   4    3  TABLE Access (FULL) OF "B"
   5    3  TABLE ACCESS (BY INDEX ROWID) OF "A"
   6    5  INDEX (RANGE SCAN) OF 
"INX_COL12A" (NON-UNIQUE)
   7    1  SORT (JOIN)
   8    7  TABLE ACCESS (FULL) OF "C"

Statistics
--------------------------------------
          0  recursive calls
          8  db block gets
          6  consistent gets
          0  physical reads
          0  redo size
        551  bytes sent via SQL*Net to client
        430  bytes received via SQL*Net from client
          2  SQL*Net roundtrips to/from client
          2  sorts (memory)
          0  sorts (disk)
          6  rows processed

在表做连接时,只能2个表先做连接,然后将连接后的结果作为一个row source,与剩下的表做连接,在上面的例子中,连接顺序为B与A先连接,然后再与C连接:

B     <---> A <--->    C
col3=10                col3=5

如果没有执行计划,分析一下,上面的3个表应该拿哪一个作为第一个驱动表?从SQL语句看来,只有B表与C表上有限制条件,所以第一个驱动表应该为这2个表中的一个,到底是哪一个呢?

B表有谓词B.col3 = 10,这样在对B表做全表扫描的时候就将where子句中的限制条件(B.col3 = 10)用上,从而得到一个较小的row source, 所以B表应该作为第一个驱动表。而且这样的话,如果再与A表做关联,可以有效利用A表的索引(因为A表的col1列为leading column)。

当然上面的查询中C表上也有谓词(C.col3 = 5),有人可能认为C表作为第一个驱动表也能获得较好的性能。让我们再来分析一下:如果C表作为第一个驱动表,则能保证驱动表生成很小的row source,但是看看连接条件A.col2 = C.col2,此时就没有机会利用A表的索引,因为A表的col2列不为leading column,这样nested loop的效率很差,从而导致查询的效率很差。所以对于NL连接选择正确的驱动表很重要。

因此上面查询比较好的连接顺序为(B - - > A) - - > C。如果数据库是基于代价的优化器,它会利用计算出的代价来决定合适的驱动表与合适的连接顺序。一般来说,CBO都会选择正确的连接顺序,如果CBO选择了比较差的连接顺序,我们还可以使用Oracle提供的hints来让CBO采用正确的连接顺序。如下所示:

select /*+ ordered */ A.col4 
from   B,A,C
where  B.col3 = 10
and    A.col1 = B.col1
and    A.col2 = C.col2
and    C.col3 = 5

SQL Server

Mssql

SQL

数据库


百度大联盟认证黄金会员Copyright© 1997- CNET Networks 版权所有。 ZDNet 是CNET Networks公司注册服务商标。
中华人民共和国电信与信息服务业务经营许可证编号:京ICP证010391号 京ICP备09041801号-159
京公网安备:1101082134