DB2 替代 EXISTS 函数
Posted
技术标签:
【中文标题】DB2 替代 EXISTS 函数【英文标题】:DB2 Alternate to EXISTS Function 【发布时间】:2013-11-13 06:04:22 【问题描述】:我在 DB2 上运行的应用程序中有以下查询:
SELECT COD.POST_CD,CLS.CLASS,COD2.STATUS_CD
FROM DC01.POSTAL_CODES COD
INNER JOIN DC02.STATUS_CODES COD2
ON COD.ORDER=COD2.ORDER
INNER JOIN DC02.VALID_ORDERS ORD
ON ORD.ORDER=COD.ORDER
WHERE
(
( EXISTS (SELECT 1 FROM DC00.PROCESS_ORDER PRD
WHERE PRD.ORDER=COD.ORDER
AND PRD.IDNUM=COD.IDNUM
)
) OR
( EXISTS (SELECT 1 FROM DC00.PENDING_ORDER PND
WHERE PND.ORDER=COD.ORDER
AND PND.IDNUM=COD.IDNUM
)
)
)
AND EXISTS (SELECT 1 FROM DC00.CUSTOM_ORDER CRD
WHERE CRD.ORDER=COD.ORDER
)
;
当我们更改为 UDB (LUW v9.5) 时,我们收到以下警告:
IWAQ0003W SQL warnings were found
SQLState=01602 Performance of this complex query might be sub-optimal.
Reason code: "3".. SQLCODE=437, SQLSTATE=01602, DRIVER=4.13.111
我知道这个警告是由于 EXISTS () OR EXISTS 语句。但我不确定是否有任何其他方式可以编写此查询来替换。如果是 AND,我可以进行 INNER JOIN,但我无法更改此条件,因为它是 OR。任何人都可以提出更好的方法来替换这些 EXISTS 语句吗?
【问题讨论】:
现在,这是一条很酷的警告消息 ;) - 如果您使用UNION
将 PENDING_ORDER 和 PROCESS_ORDER 上的两个子查询合并为一个,那么您将只有一个 EXISTS(尽管更大的结果)
呃,CLS.CLASS
引用了什么表?此外,您不能使用连接的原因是因为您正在寻找独特的结果,而不是执行和/或条件(实际上,这也不是真的,因为您可以使用作为查询的表引用) .我猜你至少可以将你的 or 条件与UNION ALL
结合起来,尽管我更喜欢使用连接......
这可能只是意味着您没有任何查询表和/或索引的当前统计信息。
自从您切换了数据库版本。可能存在影响您的错误。 www-01.ibm.com/support/docview.wss?uid=swg1IZ09197
【参考方案1】:
SELECT COD.POST_CD,CLS.CLASS,COD2.STATUS_CD
FROM DC01.POSTAL_CODES COD
INNER JOIN DC02.STATUS_CODES COD2
ON COD.ORDER=COD2.ORDER
INNER JOIN DC02.VALID_ORDERS ORD
ON ORD.ORDER=COD.ORDER
WHERE
(
EXISTS SELECT 1 FROM
(SELECT ORDER,IDNUM FROM DC00.PROCESS_ORDER PRD UNION
SELECT ORDER,IDNUM FROM DC00.PENDING_ORDER PND) PD
WHERE PD.ORDER=COD.ORDER
AND PD.IDNUM=COD.IDNUM
)
AND EXISTS (SELECT 1 FROM DC00.CUSTOM_ORDER CRD
WHERE CRD.ORDER=COD.ORDER
)
;
【讨论】:
您可能希望使用UNION ALL
代替UNION
以避免不必要的排序。以上是关于DB2 替代 EXISTS 函数的主要内容,如果未能解决你的问题,请参考以下文章
Oracle,用left join 替代 exists ,not exists,in , not in,提高效率
DB2 SQL:如何将“WHERE EXISTS”表中的列添加到选择语句
SQL Server - Exists 的替代方案(子查询太多)