首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >DB2的SQL优化

DB2的SQL优化
EN

Stack Overflow用户
提问于 2013-05-13 15:23:03
回答 3查看 722关注 0票数 0

如果您在两个结果集上执行Union操作,并且每个结果集都是从一个内部连接派生出来的,并且与主表的一个过滤子集相同,那么查询引擎是否会“命中”主表一次或两次?

示例:

代码语言:javascript
复制
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语句将处理主记录的一个小子集,而不必像上面示例中那样执行两次对主表的筛选。

谢谢你,提前,你能给出的任何建议。

EN

回答 3

Stack Overflow用户

发布于 2013-05-13 15:28:14

也许一个常见的表表达式有助于:

代码语言:javascript
复制
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的中间结果(仍然)相当大(数百万),那么这可能没有帮助。

但只有执行计划才能说明这一点。

票数 1
EN

Stack Overflow用户

发布于 2013-05-13 18:09:15

回答这类“如果”问题的最简单方法是查看查询计划。您可以使用命令db2expln -d <your db> -f <your query file> -z <your query delimiter> -gi轻松地生成一个

一般来说,如果任务可以使用单个SQL语句来完成,那么这将是完成任务的最快方法,因此创建临时表不太可能提高性能。

票数 1
EN

Stack Overflow用户

发布于 2013-05-13 15:39:12

这在很大程度上取决于所涉及的数据库和表的统计数据。我对DB2不太熟悉。

但是,如果问题是性能问题,那么考虑在master(col, col2, col3)上设置一个索引。这将加快查询的两个部分。

CTE作为临时表的使用高度特定于数据库。Postgres总是实例化CTE,因此代码只运行一次。Server从来不这样做。我不知道DB2在这方面的行为。但是,我更喜欢添加索引来显式地提高性能,而不是修改查询--当表统计信息发生变化、新软件发布或硬件升级时,您的新查询可能会导致意外的查询计划。

作为Server行为的参考,您可能对这一个这一个这一讨论感兴趣。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/16525643

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档