【问题标题】:SQL Joins Taking forever on table with 60 matchesSQL 连接永远在具有 60 个匹配项的表上
【发布时间】:2014-07-19 03:09:50
【问题描述】:

我有一个在 4 个表之间进行连接的查询。

逐个表匹配我的输入参数会产生以下结果

TrialBal - 800 万条记录匹配实体和 pl_date

加入 ActDetail - 执行时间约为 85 秒,行数为 8672175(使用 group by,行数为 1...暂时)。 ActDetail 将在内部连接上返回零行。

加入 CalendarEngine - 这个表中只有 60 条 matchig 记录(pl_date & entity),但是当这被引入 SQL 时,查询只是运行和运行。 这有什么特别的原因吗?

CalendarEngine 有一个关于实体的复合索引和我的查询中未使用的另一个字段,所以我应该仍然可以使用它吗?

为什么 TrailBal 和 ActDetail 之间的连接会相对较快(假设外部连接运行所有 800 万条记录,而 ActDetail 中的条目计数为 168k),但在 CalendarEngine 中连接 60 条记录会导致看似无休止的循环。

下面的 SQL(我需要在最终查询中注释掉的字段)。还尝试用 2 个外部连接替换 OR 语句

SELECT 
    ad.acct_lv2 AS IFRS_lvl2,
    ad.acct_lv3 AS IFRS_lvl3,
    ad.acct_lv4 AS IFRS_lvl4,
    ad.acct_lv6 AS IFRS_lvl6,
    --(CASE WHEN tb.pl_date = cal.curr_me_date THEN cal.date END) as Reporting_Cycle_This,
    --(CASE WHEN tb.pl_date = cal.prev_me_date THEN cal.date END) as Reporting_Cycle_Last,
    --(CASE WHEN tb.pl_date = cal.prev_me_date THEN cal.date END) as Reporting_Cycle_Previous,
    null as Total,
    null as Balance_default_dim,
    null as Balance_proxy_dim,
    0 as percentage_bal_proxy_applied,
    '1 Table Data' as rowType 
FROM TrialBal tb 
INNER JOIN Partition p ON p.partition_code = tb.partition_code
    AND p.entity = tb.entity
LEFT OUTER JOIN ActDetail ah ON tb.actNum = ad.actNum
    AND tb.cpny = ad.cpny
    AND tb.pl_date = ad.pl_date
    AND ad.source = 'Ground0'
--LEFT OUTER JOIN CalendarEngine cal on tb.pl_date = cal.curr_me_date OR tb.pl_date = cal.prev_me_date
    --AND tb.entity = cal.entity
WHERE tb.pl_date = '2014-04-30'
AND tb.entity = 'My_entity'
GROUP BY ad.acct_lv2, ad.acct_lv3, ad.acct_lv4, ad.acct_lv6, --tb.actNum, tb.cpny, 
    CASE WHEN tb.pl_date = cal.curr_me_date THEN cal.date END,
    CASE WHEN tb.pl_date = cal.prev_me_date THEN cal.date END,
    CASE WHEN tb.pl_date = cal.prev_me_date THEN cal.date END

还尝试用 2 个外部连接替换 OR 语句:

LEFT OUTER JOIN sCalendar cal_cur on tb.pnl_date = cal_cur.curr_me_date
    AND tb.entity_code = cal_cur.entity_code
LEFT OUTER JOIN sCalendar cal_pre on tb.pnl_date = cal_pre.prev_me_date
    AND tb.entity_code = cal_pre.entity_code

【问题讨论】:

    标签: sql join sybase large-data


    【解决方案1】:

    在 cal.curr_me_date 和 tb.pl_date 上有索引吗?当我遇到类似问题时,我会在我的连接字段上查找索引,这就是解决方法。

    【讨论】:

    • tb.pl_date 是 TrialBalance 索引的一部分,所以我想我可以使用它。 cal_curr_me_date 不是 CalcEngine 上的索引字段 - 我会看看是否可以添加它。
    • 我已经添加了索引,仍然等待 40 多分钟才能执行。问题只是数据集的大小吗?
    • 遗憾的是,这并没有什么不同。在终止之前让查询运行 15 小时。嗯,接下来怎么办……
    【解决方案2】:

    你为什么要做这个加入

    LEFT OUTER JOIN ActDetail ah ON tb.actNum = ad.actNum
    AND tb.cpny = ad.cpny
    AND tb.pl_date = ad.pl_date
    AND ad.source = 'Ground0'
    

    我没有看到该列的任何用途,删除不必要的连接。

    如果这部分是日期

    tb.pl_date = '2014-04-30'
    

    我建议使用

     pl_date >= dateadd(d,0,datediff(d,0,pl_date)) and pl_date < dateadd(d,0,datediff(d,0,pl_date+1))
    

    问候

    【讨论】:

      猜你喜欢
      • 2019-05-29
      • 2015-01-05
      • 1970-01-01
      • 1970-01-01
      • 2013-05-08
      • 2019-12-10
      • 1970-01-01
      • 2018-12-19
      相关资源
      最近更新 更多