优化MS-SQL查询

时间:2014-07-22 12:53:02

标签: sql sql-server

我正在努力解决一个MS-sql查询的问题,我必须在ERP系统中创建一个报告。

希望你可以帮我解决这个问题。

以下是查询:

"原始版本":

SELECT artikel.artikelnummer, artikel.bezeichnung, SUM(positionen.anzahl), artikel.Einheit
FROM artikel, auftrag, positionen 
INNER JOIN auftrag AS auftrag1 ON (auftrag1.auftrag = positionen.auftrag) 
INNER JOIN artikel AS artikel1 ON (positionen.artikel = artikel1.artikel)
WHERE 
artikel.warengruppe = 2
OR artikel.warengruppe = 1234
OR artikel.warengruppe = 1235
OR artikel.warengruppe = 1236
OR artikel.warengruppe = 1237
OR artikel.warengruppe = 1239
OR artikel.warengruppe = 1240
OR artikel.warengruppe = 2139
AND auftrag.lieferscheinnr IS NOT NULL
GROUP BY artikel.artikelnummer, artikel.bezeichnung,artikel.Einheit

"翻译版本":

SELECT article.articlenr, article.description, SUM(positions.amount), article.unit
FROM article, order, positions
INNER JOIN order AS order1 ON (order1.order = positions.order) 
INNER JOIN article AS article1 ON (positions.article = article1.article)
WHERE 
article.materialgroup = 2
OR article.materialgroup = 1234
OR article.materialgroup = 1235
OR article.materialgroup = 1236
OR article.materialgroup = 1237
OR article.materialgroup = 1239
OR article.materialgroup = 1240
OR article.materialgroup = 2139
AND order.dordernr IS NOT NULL
GROUP BY article.articlenr, article.description,article.unit

我们想要计算所有交货单(DO)的墨水量。 在表格" auftrag"我有所有DO编号和订单编号。 在表格#34; positionen"我有几个订单的所有头寸,包括适量的墨水瓶。 在表格" artikel"我有所有的文章细节,如描述,瓶子大小等。 专栏" artikel.warengruppe"包含包含墨水的正确材料组。

现在的问题是桌子" auftrag"包含160.000," artikel" 155.000和positionen 570.000条目。

我在运行1小时后中止查询。 所以我的问题是如何优化查询?

我的问题是我无法改变ER模型。

非常感谢您的帮助。我希望你能理解我糟糕的英语。 ;)

4 个答案:

答案 0 :(得分:2)

如果您正确地表达where子句,那么性能可能会提高。我建议:

WHERE artikel.warengruppe in (2, 1234, 1235, 1236, 1237, 1239, 1240, 2139) and
      auftrag.lieferscheinnr IS NOT NULL;

您的逻辑是找到前7个warengruppe值的所有内容。然后,它还在寻找2139 lieferscheinnr IS NOT NULL

其次,您需要修复from子句。它应该是这样的:

FROM artikel
INNER JOIN auftrag AS auftrag1 ON (auftrag1.auftrag = positionen.auftrag) 
INNER JOIN artikel AS artikel1 ON (positionen.artikel = artikel1.artikel)

请避免使用from子句中的逗号。你的查询是在所有表格中做了大量的笛卡尔积,然后然后重新加入表格。这是一项令人难以置信的工作量。

答案 1 :(得分:0)

除了索引之外,这样的内容会为您提供所需的结果:

SELECT article.articlenr, article.description, SUM(positions.amount), article.unit
FROM positions
    INNER JOIN order AS order1 ON (order1.order = positions.order) 
    INNER JOIN article AS article1 ON (positions.article = article1.article)
WHERE 
    EXISTS (SELECT *
            FROM article a
            WHERE materialgroup IN (2,1234, 1235, 1236, 1237, 1239, 1240, 2139)
                AND a.article = article1.article)
AND order.dordernr IS NOT NULL
GROUP BY article.articlenr, article.description,article.unit

答案 2 :(得分:0)

您应该检查执行计划。这是technet上的一个链接,可以帮助您: http://technet.microsoft.com/en-us/library/ms178071(v=sql.105).aspx。 它会告诉你应该添加或更改哪些索引(我想知道列artikel.warengruppe是否已编入索引)。 如果您发布执行计划,SO上的人员将真的能够帮助您。

答案 3 :(得分:0)

也许是这样的:

DECLARE @Articles TABLE (id INT);
 INSERT @Articles (id)
 VALUES (2), (1234), (1235), (1236), (1237), (1239), (1240), (2139);

 SELECT article.articlenr, article.description, SUM(positions.amount), article.unit
   FROM article, order, positions
  INNER JOIN [order] AS order1 ON (order1.order = positions.order) AND order.dordernr IS NOT NULL
  INNER JOIN article AS article1 ON (positions.article = article1.article)
  INNER JOIN @Articles AS Art ON Art.id = article.materialgroup
  GROUP BY article.articlenr, article.description, article.unit