【问题标题】:DB2 Union causes time out?DB2 Union 导致超时?
【发布时间】:2012-11-14 09:38:12
【问题描述】:

第一次使用 DB2。我有一个执行联合的存储过程,无论如何它都会尝试。该过程超时。联合两侧的 select 语句在单独执行时快速执行,没有问题。为什么工会会这样做?

这里是 proc 的一些 sudo 代码,假设数据类型是 int 或 string,并且它们在比较或联合时匹配,除非 SQL 中另有说明:

DECLARE Foo CURSOR WITH RETURN FOR
  Select STRIP(A.Name) as my_Name, 
     Case A.Number
        when 2 then '(' || strip(char(A.Number)) || ')' strip(B.num)
        when 3 then '(' || strip(char(A.Number)) || ')' strip(C.num)
        when 4 then '(' || strip(char(A.Number)) || ')' strip(D.num)
        when 5 then '(' || strip(char(A.Number)) || ')' strip(E.num)
        when 6 then '(' || strip(char(A.Number)) || ')' strip(F.num)
        end as my_number
  FROM A
       left outer join B on A.Number= 2 and A.Name = B.Name
       left outer join C on A.Number= 3 and C.Name = B.Name
       left outer join D on A.Number= 4 and D.Name = B.Name
       left outer join E on A.Number= 5 and E.Name = B.Name
       left outer join F on A.Number= 6 and F.Name = B.Name 
      ,session.Temp_Result X
  WHERE X.ID = A.ID
  GROUP BY A.Number, A.Name, B.Name, C.Name, D.Name, E.Name, F.Name
for fetch only ur;

DROP TABLE Session.Temp_Result;

DECLARE GLOBAL TEMPORARY TABLE session.Temp_Result
(     ID DECIMAL(18,0)
);

INSERT INTO session.Temp_Result
        select X.ID
        from Z, Y, X, Q
        where Z.num = 6
          and Z.ID = Y.ID2
          and Y.GROUPA = 'ABC'
          and Y.GROUPB = 'DEF'
          and Y.ID = X.ID2
          and X.ID = Q.ID            
        union
       select W.ID
        from Z, Y, W
        where Z.num = 6
          and Z.ID = Y.ID2
          and Y.GROUPA = 'ABC'
          and Y.GROUPB = 'DEF'
          and Y.ID = W.ID2
        group by ID;


  OPEN C_HIERARCHIES;

【问题讨论】:

  • 请发布SELECT语句,以及涉及的每一列的类型。
  • 鉴于UNION 删除了重复项,我觉得这是问题的一部分。 (每条语句)返回了多少行,索引是什么等,可能是有用的信息。
  • 每个语句此时返回大约 5 个 ID。直到明天我才能得到任何索引信息。

标签: sql performance timeout db2


【解决方案1】:

我的猜测是原始代码缺少伪代码中存在的连接条件。您应该使用正确的连接语法重写查询以验证查询。

在任何情况下,如果每个子查询都运行得很快,并且联合存在一些不正常的后果,您可以尝试将其拆分为两个插入:

INSERT INTO session.Temp_Result
    select X.ID
    from Z, Y, X, Q
    where Z.num = 6
      and Z.ID = Y.ID2
      and Y.GROUPA = 'ABC'
      and Y.GROUPB = 'DEF'
      and Y.ID = X.ID2
      and X.ID = Q.ID;

INSERT INTO session.Temp_Result
   select W.ID
    from Z, Y, W
    where Z.num = 6
      and Z.ID = Y.ID2
      and Y.GROUPA = 'ABC'
      and Y.GROUPB = 'DEF'
      and Y.ID = W.ID2
    group by ID;

那么你可以查询 Temp_Result 为:

select distinct id from TempResult

删除重复项似乎没有必要,因为数据非常小,但您也可以直接这样做。

【讨论】:

    【解决方案2】:

    尝试使用“with”语句查询。

    DECLARE GLOBAL TEMPORARY TABLE session.Temp_Result (
    ID DECIMAL(18,0))
    WITH REPLACE;
    
    INSERT INTO session.Temp_Result
    (ID)
    WITH Q1(Y_ID)
    AS (
    SELECT Y.ID
    FROM Z
        INNER JOIN Y ON Z.ID = Y.ID2
    WHERE Z.NUM = 6 AND Y.GROUPA = 'ABC' AND Y.GROUPB = 'DEF')
    
    SELECT X.ID
    FROM X
        INNER JOIN Q1 ON X.ID2 = Q1.Y_ID
    WHERE EXISTS(SELECT 1 FROM Q WHERE Q.ID = X.ID)
    UNION
    SELECT DISTINCT W.ID
    FROM W
        INNER JOIN Q1 ON W.ID2 = Q1.Y_ID
    

    如果没有帮助,请尝试对 select 语句使用“解释 SQL”。也许你应该创建一些索引...

    【讨论】:

    • 如果我能看到表的索引方式并在必要时修改它们,那将是理想的,但是在当前环境中这是不可能的。
    • 下面第三行中的 WITH REPLACE 语句会导致存储过程中出现错误,但是,删除该语句后,程序的执行得到了改善,并且不再超时。
    • 将两个 select 语句的重复部分组合起来,并且只执行一次,这样会更有效率。不过,我有点惊讶这可以解决这个问题。两个 select 语句分别在不到一秒的时间内执行。我认为这意味着由于联合,DB2 在执行 select 时使用一个 select 语句从另一个语句中过滤结果
    猜你喜欢
    • 1970-01-01
    • 2018-05-16
    • 2016-09-24
    • 2021-10-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多