使用连接过滤器和连接后过滤器

数据库服务器提供对使用 ANSI 连接语法的子集的支持:

此语法包括以下关键字:

有关此 ANSI 连接语法的更多信息,请参阅 GBase 8s SQL 指南:语法

在 ANSI 外连接中,数据库服务器执行以下操作来处理过滤器:

执行使用符合 ANSI 的 LEFT OUTER 语法以用来指定连接表和嵌套循环连接的分发查询时,将查询发送到每个参与的数据库服务器以对这些服务器的本地表执行操作。

例如,演示数据库中的 customer 表和 cust_calls 表可以跟踪客户呼叫服务部门的情况。假设某个呼叫代码在过去出现多次,而您希望了解此类呼叫是否已减少。 要了解客户是否不再进行该呼叫代码的呼叫,可使用外连接列出所有客户。

图 1 显示了样本 SQL 语句,该 语句完成此 ANSI 连接查询及其 SET EXPLAIN ON 输出。

图: ANSI 连接的 SET EXPLAIN ON 输出

QUERY:
------
SELECT c.customer_num, c.lname, c.company,
c.phone, u.call_dtime, u.call_code, u.call_descr
FROM customer c
LEFT JOIN cust_calls u ON c.customer_num = u.customer_num
ORDER BY u.call_dtime

Estimated Cost: 14
Estimated # of Rows Returned: 29
Temporary Files Required For: Order By

1) virginia.c: SEQUENTIAL SCAN

2) virginia.u: INDEX PATH

   (1) Index Keys: customer_num call_dtime (Serial, fragments: ALL)
     Lower Index Filter: virginia.c.customer_num = virginia.u.customer_num

  ON-Filters:virginia.c.customer_num = virginia.u.customer_num
  NESTED LOOP JOIN(LEFT OUTER JOIN)
请查看图 1 的 SET EXPLAIN ON 输出的以下行:
图 2 显示了 ANSI 连接的 SET EXPLAIN ON 输出,其中连接过滤器检查呼叫代码为 I 的呼叫。

图: ANSI 连接中连接过滤器的 SET EXPLAIN ON 输出

QUERY:
------
SELECT c.customer_num, c.lname, c.company,
c.phone, u.call_dtime, u.call_code, u.call_descr
FROM customer c LEFT JOIN cust_calls u
ON c.customer_num = u.customer_num
AND u.call_code = 'I'
ORDER BY u.call_dtime

Estimated Cost: 13
Estimated # of Rows Returned: 25
Temporary Files Required For: Order By

  1) virginia.c: SEQUENTIAL SCAN

  2) virginia.u: INDEX PATH

     Filters: virginia.u.call_code = 'I'

      (1) Index Keys: customer_num call_dtime   (Serial, fragments: ALL)
          Lower Index Filter: virginia.c.customer_num = virginia.u.customer_num

ON-Filters:(virginia.c.customer_num = virginia.u.customer_num
               AND virginia.u.call_code = 'I' )
NESTED LOOP JOIN(LEFT OUTER JOIN)
图 1图 2 中的输出之间的主要区别如下:

Estimated # of Rows Returned 行中的值只是估计值,并不总是反映实际返回的行数。 由于有附加过滤器,图 2 中的样本查询返回的行比图 1 中的查询返回的要少。

图 3 显示 ANSI 连接查询的 SET EXPLAIN ON 输出,该连接查询在 WHERE 子句中具有一个过滤器。

图: ANSI 连接中 WHERE 子句过滤器的 SET EXPLAIN ON 输出

QUERY:
------
SELECT c.customer_num, c.lname, c.company,
   c.phone, u.call_dtime, u.call_code, u.call_descr
FROM customer c LEFT JOIN cust_calls u
ON c.customer_num = u.customer_num
   AND u.call_code = 'I'
WHERE c.zipcode = "94040"
ORDER BY u.call_dtime

Estimated Cost: 3
Estimated # of Rows Returned: 1
Temporary Files Required For: Order By

  1) virginia.c: INDEX PATH

    (1) Index Keys: zipcode   (Serial, fragments: ALL)
        Lower Index Filter: virginia.c.zipcode = '94040'

  2) virginia.u: INDEX PATH

     Filters: virginia.u.call_code = 'I'

    (1) Index Keys: customer_num call_dtime   (Serial, fragments: ALL)
        Lower Index Filter: virginia.c.customer_num = virginia.u.customer_num

ON-Filters:(virginia.c.customer_num = virginia.u.customer_num
      AND virginia.u.call_code = 'I' )
NESTED LOOP JOIN(LEFT OUTER JOIN)

PostJoin-Filters:virginia.c.zipcode = '94040'
图 2图 3 中的输出之间的主要区别如下: