使用列过滤器的连接的示例

列过滤器 的存在会更改查询计划。列过滤器是 WHERE 表达式,该表达式减少表加入到连接的行数。

以下示例显示了查询计划执行示例中所述的带有添加的过滤器的查询:
SELECT C.customer_num, O.order_num
   FROM customer C, orders O, items I
   WHERE C.customer_num = O.customer_num
      AND O.order_num = I.order_num
            AND O.paid_date IS NULL
表达式 O.paid_date IS NULL 过滤掉一些行,从而减少 orders 表中所使用的行数。 请设想一个计划,该计划是通过从 orders 读取开始的。图 1 以伪码显示该样本。

图: 使用列过滤器的查询计划

for each row in the orders table do:
      read the row into O
         if O.paid_date is null then
            for each row in the customer table do:
                  read the row into C
                  if O.customer_num = C.customer_num then
                        for each row in the items table do:
                              read the row into I
                              if I.order_num = O.order_num then
                                 accept row and return to user
                  end if
               end for 
            end if
         end for 
      end if
   end for 
pdnull 表示 orders 中通过过滤器的行数。它是从以下查询得出的 COUNT(*) 的值:
SELECT COUNT(*) FROM orders WHERE paid_date IS NULL
如果每个 order 都有一个 customer,那么图 1 中的计划将读取以下行:
图 2 显示了一个备选的执行计划,该计划首先从 customer 表读取。

图: 以伪码编写的备用查询计划

      for each row in the customer table do:
            read the row into C
   for each row in the orders table do:
         read the row into O
            if O.paid_date is null and
                      O.customer_num = C.customer_num then
                     for each row in the items table do:
                           read the row into I
                           if I.order_num = O.order_num then
                              accept row and return to user
               end if
            end for 
         end if
      end for 
因为过滤器没有在图 2 显示的第一步中应用,所以该计划读取以下行:

图 1图 2 中的查询计划以不同的顺序产生相同的输出。这两个查询计划的不同之处在于:一个读取表 pdnull 次,而另一个读取表 SELECT COUNT (*)FROM customer 次。通过选择适当的计划,优化器可以将成千上万的磁盘存取保存在某个实际的应用程序中。