2014-10-07 98 views
0

我正在为现有应用程序编写一个附加项,并且需要为各种事务类型获取数量总和。每个事务类型都有一套独特的标准ta_code,ta_type和ta_asc在大型表上优化多重连接查询

下查询并返回所需的信息,但最终,trans表中有大约500万条记录,因此需要4分钟,运行

SELECT t.qty AS tQty, sQty, rQty, mQty, lQty, aQty, xQty, t.itmcode 
FROM trans AS t 
LEFT JOIN 
    (
     SELECT sum(qty) as sQty, itmcode 
     FROM trans 
     WHERE 
      site = 127 
      AND ta_code = '12' 
     GROUP BY itmcode 
    )as tblS ON tblS.itmcode = t.itmcode 
LEFT JOIN 
    (
     SELECT sum(qty) as rQty, itmcode 
     FROM trans 
     WHERE 
      site = 127 
      AND ta_code = '12' AND ta_type = '1' 
     GROUP BY itmcode 
    )as tblR ON tblR.itmcode = t.itmcode 
LEFT JOIN 
    (
     SELECT sum(qty) as mQty, itmcode 
     FROM trans 
     WHERE 
      site = 127 
      AND ta_code = '15' AND ta_type = '4' 
     GROUP BY itmcode 
    )as tblM ON tblM.itmcode = t.itmcode 
LEFT JOIN 
    (
     SELECT sum(qty) as lQty, itmcode 
     FROM trans 
     WHERE 
      site = 127 
      AND ta_asc = '147' 
     GROUP BY itmcode 
    )as tblL ON tblL.itmcode = t.itmcode 
LEFT JOIN 
    (
     SELECT sum(qty) as aQty, itmcode 
     FROM trans 
     WHERE 
      site = 127 
      AND ta_asc = '155' 
     GROUP BY itmcode 
    )as tblA ON tblA.itmcode = t.itmcode 
LEFT JOIN 
    (
     SELECT sum(qty) as xQty, itmcode 
     FROM trans 
     WHERE 
      site = 127 
      AND ta_asc = '155' AND ta_code = '15' AND ta_type = '4' 
     GROUP BY itmcode 
    )as tblX ON tblX.itmcode = t.itmcode     
INNER JOIN item AS i ON i.code = t.itmcode  
WHERE t.site = 127 
GROUP BY itmcode 

每个连接似乎都会增加无效率,但即使单独运行,每个连接选择也需要10秒才能运行。我们只能读取这个数据库,所以不能以任何方式改变它。

如果有人能够建议一种可以更有效地实现这一点的方法或结构,我将不胜感激。

+0

取决于各种因素,你可能会得到巨大的改进复制数据在一个单独的表你可以优化(索引等)。数据更新的频率如何?你多久运行一次查询? – Paolo 2014-10-07 07:50:50

+0

在SELECT字段部分中移动您的LEFT JOIN。所以你的表格将被转换为AS t JOIN项目AS i – 2014-10-07 07:52:16

+0

感谢您的答复。我想我会使用创建一个新表来存储查询收到的历史总计,而不是每次计算,并按照亚历克斯·布尼的建议更换联接以获取新信息 – user2552985 2014-10-08 20:44:42

回答

1

这可能是值得一试:删除所有“左连接”的条款,并计算有条件的总和,这样的事情:

SELECT 
    ISNULL(SUM(CASE WHEN ta_code = '12' and ta_type='1' THEN Qty ELSE 0 END), 0) as rQty, 
    ISNULL(SUM(CASE WHEN ta_code = '15' and ta_type='4' THEN Qty ELSE 0 END), 0) as mQty 

    FROM trans AS t 

    WHERE t.Site = 127 
    GROUP BY itmcode 
+0

可能会将此标记为答案,因为获得所有总计所需的时间并不比每次选择所需的时间长得多。好的方法。 – user2552985 2014-10-08 20:49:23

+0

请标记为答案:) – 2014-10-09 00:49:04

1

这里有一些事情,我会尝试:

  1. 在itmCode列
  2. 添加索引移动INNER JOIN项目正如我在i.code = t.itmcode作为第一个加入
  3. 将“SELECT sum(qty)as sQty,itmcode FROM trans WHERE site = 127 AND ta_code ='12' GROUP BY itmcode”用作临时表,然后在其他左连接中将其用于adda ta_type,因为您重复此操作不必要地在每个左连接中查询。

我也总是建议学习和使用MS SQL配置文件,如果您使用的是MS SQL。

+0

感谢您只需将联接的执行时间缩短约40% – user2552985 2014-10-08 20:46:11

+0

非常感谢+1 – 2014-10-09 03:46:19