【问题标题】:Optimization DB2 query with mass join使用批量连接优化 DB2 查询
【发布时间】:2014-05-19 18:29:18
【问题描述】:

我有复杂的查询:

select rma.RELATION_MANAGER_ID,
       rm.ORG_STRUCTURE_ID,
       rm.RELATIONSHIP_MANAGER_NM,
       count(distinct ppa.PARTY_ID) as count_party
from RELATIONSHIP_MANAGER rm --15808 row
join RELATIONSHIP_MANAGER_MARKET rmm --1560 row
   on rm.RELATIONSHIP_MANAGER_ID = rmm.RELATIONSHIP_MANAGER_ID
      and rmm.INCLUDE_IN_REPORT = 'Y'
join MARKET_SEGMENT rm_ms --4 row
   on rmm.MARKET_SEGMENT_ID = rm_ms.MARKET_SEGMENT_ID
      and rm_ms.MARKET_SEGMENT = '01'
join RELATIONSHIP_MANAGER_ALLOCATION rma --61349 row
   on rm.RELATIONSHIP_MANAGER_ID = rma.RELATIONSHIP_MANAGER_ID
join CMD_PARTY_PORTFOLIO_ALLOCATION ppa --3114096 row
   on ppa.PORTFOLIO_ID = rma.PORTFOLIO_ID
join person ps --3112575 row
   on ps.IS_DELETED != 1 and ppa.party_id = ps.party_id
join PARTY p  --3114146 row
   on ppa.party_id=p.party_id
join MARKET_SEGMENT ms --4 row
   on  p.MARKET_SEGMENT_ID = ms.MARKET_SEGMENT_ID and ms.MARKET_SEGMENT = '01'
   where rm.IS_CM = 1 and rm.IS_DELETED != 1
group by rm.RELATIONSHIP_MANAGER_NM, rma.RELATIONSHIP_MANAGER_ID, rm.ORG_STRUCTURE_ID

表列有索引:

rm.RELATIONSHIP_MANAGER_ID,
rmm.RELATIONSHIP_MANAGER_ID,
rmm.MARKET_SEGMENT_ID,
rm_ms.MARKET_SEGMENT_ID,
rma.RELATIONSHIP_MANAGER_ID,
ppa.PORTFOLIO_ID,
rma.PORTFOLIO_ID,
ppa.party_id,
ps.party_id,
p.party_id,
p.MARKET_SEGMENT_ID,
ms.MARKET_SEGMENT_ID

表 PARTY、PERSON 有大约 1-3 百万行, 查询运行时间约 20 秒。我是评论

join MARKET_SEGMENT ms 
on  p.MARKET_SEGMENT_ID = ms.MARKET_SEGMENT_ID --and ms.MARKET_SEGMENT = '01'

查询的运行时间变为约 3 秒。 请解释一下为什么会这样? 解释计划对我没有帮助。我如何优化查询?

编辑: 平台是 DB2 for z/OS V9.7, 增加表格大小

EDIT2:解释计划显示第一个总是加入小尺寸表

【问题讨论】:

  • MARKET_SEGMENT 没有索引,它是文本。如果您在On 子句中有该比较,您将为每个Join 执行该比较。要么将该条件放在Where 子句中,要么在MARKET_SEGMENT 上放置一个索引。
  • market_segment 与文本比较时,索引可能不起作用。
  • 优化是平台相关的,如果不是版本相关的。您的 DB2 服务器在哪个平台上运行:IBM i、LUW 或 z/OS?
  • 对不起,平台是 z/OS 9.7
  • @Siyual - 使用JOINs(即INNER JOINs),将条件作为连接条件的一部分或WHERE 子句中没有语义上的区别;优化器已经在移动条件(并重新排序JOINs!)它认为合适。不过,OP 可能应该将该列添加到索引中。它是基于字符的(相对于任何其他类型)这一事实与所选择的条件无关(数字类型(可能)具有相同的效果)。

标签: sql database db2 query-optimization


【解决方案1】:

只是为了笑,看看这是否有什么不同:

WITH
MktSeg( MARKET_SEGMENT_ID ) AS
( SELECT  MARKET_SEGMENT_ID
  FROM    MARKET_SEGMENT
  WHERE   MARKET_SEGMENT = '01' )
select rma.RELATION_MANAGER_ID,
       rm.ORG_STRUCTURE_ID,
       rm.RELATIONSHIP_MANAGER_NM,
       count(distinct ppa.PARTY_ID) as count_party
from RELATIONSHIP_MANAGER rm --15808 row
join RELATIONSHIP_MANAGER_MARKET rmm --1560 row
   on rm.RELATIONSHIP_MANAGER_ID = rmm.RELATIONSHIP_MANAGER_ID
      and rmm.INCLUDE_IN_REPORT = 'Y'
join MktSeg rm_ms --4 row
   on rmm.MARKET_SEGMENT_ID = rm_ms.MARKET_SEGMENT_ID
join RELATIONSHIP_MANAGER_ALLOCATION rma --61349 row
   on rm.RELATIONSHIP_MANAGER_ID = rma.RELATIONSHIP_MANAGER_ID
join CMD_PARTY_PORTFOLIO_ALLOCATION ppa --3114096 row
   on ppa.PORTFOLIO_ID = rma.PORTFOLIO_ID
join person ps --3112575 row
   on ps.IS_DELETED != 1 and ppa.party_id = ps.party_id
join PARTY p  --3114146 row
   on ppa.party_id=p.party_id
join MktSeg ms --4 row
   on  p.MARKET_SEGMENT_ID = ms.MARKET_SEGMENT_ID
WHERE rm.IS_CM = 1 AND rm.IS_DELETED != 1
group by rm.RELATIONSHIP_MANAGER_NM, rma.RELATIONSHIP_MANAGER_ID,
         rm.ORG_STRUCTURE_ID, rma.RELATION_MANAGER_ID

还请注意,我已在 Group By 子句中添加了一个项目。

【讨论】:

  • 运行时是一样的。我注意到解释计划太相似了。我试图重写不同的设计,但解释计划没有改变。
猜你喜欢
  • 1970-01-01
  • 2017-03-17
  • 2012-09-26
  • 1970-01-01
  • 2016-10-07
  • 1970-01-01
  • 2023-03-12
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多