如果您在两个结果集上执行Union操作,并且每个结果集都是从一个内部连接派生出来的,并且与主表的一个过滤子集相同,那么查询引擎是否会“命中”主表一次或两次?
示例:
SELECT m.col4, st1.col2
FROM master m
INNER JOIN subTable1 st1
on st1.col1 = m.col1
WHERE m.col1 = 'a' and m.col2 = 123 and m.col3 = "a1b2"
UNION ALL
SELECT m.col4, st2.col2
FROM master m
INNER JOIN subTable2 st2
on st2.col1 = m.col1
WHERE m.col1 = 'a' and m.col2 = 123 and m.col3 = "a1b2"我试图确定创建一个临时表以保存主表的过滤结果是否有益,这样UNION ALL语句将处理主记录的一个小子集,而不必像上面示例中那样执行两次对主表的筛选。
谢谢你,提前,你能给出的任何建议。
发布于 2013-05-13 15:28:14
也许一个常见的表表达式有助于:
with small_master as (
select m.col4,
m.col1
from master
where m.col1 = 'a'
and m.col2 = 123
and m.col3 = 'a1b2'
)
SELECT m.col4, st1.col2
FROM small_master m
INNER JOIN subTable1 st1
on st1.col1 = m.col1
UNION ALL
SELECT m.col4, st2.col2
FROM small_master m
INNER JOIN subTable2 st2
on st2.col1 = m.col1;根据我的经验(但不是使用DB2 ),如果CTE大幅度减少行数(例如从“数百万”减少到“数千”),这会有所帮助。
如果CTE的中间结果(仍然)相当大(数百万),那么这可能没有帮助。
但只有执行计划才能说明这一点。
发布于 2013-05-13 18:09:15
回答这类“如果”问题的最简单方法是查看查询计划。您可以使用命令db2expln -d <your db> -f <your query file> -z <your query delimiter> -gi轻松地生成一个
一般来说,如果任务可以使用单个SQL语句来完成,那么这将是完成任务的最快方法,因此创建临时表不太可能提高性能。
发布于 2013-05-13 15:39:12
这在很大程度上取决于所涉及的数据库和表的统计数据。我对DB2不太熟悉。
但是,如果问题是性能问题,那么考虑在master(col, col2, col3)上设置一个索引。这将加快查询的两个部分。
CTE作为临时表的使用高度特定于数据库。Postgres总是实例化CTE,因此代码只运行一次。Server从来不这样做。我不知道DB2在这方面的行为。但是,我更喜欢添加索引来显式地提高性能,而不是修改查询--当表统计信息发生变化、新软件发布或硬件升级时,您的新查询可能会导致意外的查询计划。
作为Server行为的参考,您可能对这一个、这一个或这一讨论感兴趣。
https://stackoverflow.com/questions/16525643
复制相似问题