嵌套视图性能

时间:2013-05-14 10:06:36

标签: sql sql-server performance view

我有这个SQL查询:

SELECT Start,
    ISNULL((SELECT Orders FROM [pp].dbo.VW_BEZETTING_RAW b2 WHERE b2.Start=b1.Start AND Afdeling = 'WP'),0) AS Werkplaats_ord,
    ISNULL((SELECT Tijd FROM [pp].dbo.VW_BEZETTING_RAW b2 WHERE b2.Start=b1.Start AND Afdeling = 'WP'),0) AS Werkplaats_tijd, 
    ISNULL((SELECT Orders FROM [pp].dbo.VW_BEZETTING_RAW b2 WHERE b2.Start=b1.Start AND Afdeling = 'MAG'),0) AS Magazijn_ord,
    ISNULL((SELECT Tijd FROM [pp].dbo.VW_BEZETTING_RAW b2 WHERE b2.Start=b1.Start AND Afdeling = 'MAG'),0) AS Magazijn_tijd, 
    ISNULL((SELECT Orders FROM [pp].dbo.VW_BEZETTING_RAW b2 WHERE b2.Start=b1.Start AND Afdeling = 'SERV'),0) AS Service_ord,
    ISNULL((SELECT Tijd FROM [pp].dbo.VW_BEZETTING_RAW b2 WHERE b2.Start=b1.Start AND Afdeling = 'SERV'),0) AS Service_tijd, 
    ISNULL((SELECT Orders FROM [pp].dbo.VW_BEZETTING_RAW b2 WHERE b2.Start=b1.Start AND Afdeling = 'CNC'),0) AS Draaibank_ord,
    ISNULL((SELECT Tijd FROM [pp].dbo.VW_BEZETTING_RAW b2 WHERE b2.Start=b1.Start AND Afdeling = 'CNC'),0) AS Draaibank_tijd, 
    ISNULL((SELECT Orders FROM [pp].dbo.VW_BEZETTING_RAW b2 WHERE b2.Start=b1.Start AND Afdeling = 'SECL'),0) AS Bougiekabels_ord,
    ISNULL((SELECT Tijd FROM [pp].dbo.VW_BEZETTING_RAW b2 WHERE b2.Start=b1.Start AND Afdeling = 'SECL'),0) AS Bougiekabels_tijd 
FROM [pp].dbo.VW_BEZETTING_RAW b1
GROUP BY Start

我可以解释一下我的查询是做什么的,但我不认为这是相关的,因为查询已经正常工作。我唯一的问题是处理时间;我必须等待20-25秒才能获得结果,我认为这有点长。

SQL Server似乎做了什么(我认为),SELECT我的值是[pp].dbo.VW_BEZETTING_RAW的11倍(每个子查询10次,普通查询1次)。这是一项繁重的任务,因为SELECT * FROM [pp].dbo.VW_BEZETTING_RAW的处理时间约为2秒。 SELECT不是必需的,它应该足以引用它一次并在每个子查询中使用结果。我测试了我的性能问题是否真的是因为子查询,它是:当我将查询减少到只有2而不是10个子查询时,处理时间只有6-7秒。

仅供参考,以下是[pp].dbo.VW_BEZETTING_RAW的结果的一部分:

    Start       Afdeling    Orders  Tijd
    2013-05-14  SERV        3       0
    2013-05-14  WP          17      0
    2013-05-15  MAG         1       0
    2013-05-15  SERV        3       0
    2013-05-15  WP          14      0
    2013-05-16  CNC         1       0
    2013-05-16  MAG         9       0
    2013-05-16  SERV        3       0
    2013-05-16  WP          22      0
    2013-05-17  MAG         19      0
    2013-05-17  WP          8       0
    2013-05-20  MAG         11      0

我明确的问题是:是否可以SELECT[pp].dbo.VW_BEZETTING_RAW SELECT次结果并在每个子查询中使用此结果(而不是触发此{{1}}次查询10次再次),或者,如果不可能,还有其他方法可以缩短查询的处理时间吗?

2 个答案:

答案 0 :(得分:5)

此查询应解决您的问题(包括您是否可以使用负订单/时间值)。

SELECT Start,
    ISNULL(MIN(CASE WHEN Afdeling = 'WP' THEN Orders END),0) AS Werkplaats_ord,
    ISNULL(MIN(CASE WHEN Afdeling = 'WP' THEN Tijd END),0) AS Werkplaats_tijd, 
    ISNULL(MIN(CASE WHEN Afdeling = 'MAG' THEN Orders END),0) AS Magazijn_ord,
    ISNULL(MIN(CASE WHEN Afdeling = 'MAG' THEN Tijd END),0) AS Magazijn_tijd, 
    ISNULL(MIN(CASE WHEN Afdeling = 'SERV' THEN Orders END),0) AS Service_ord,
    ISNULL(MIN(CASE WHEN Afdeling = 'SERV' THEN Tijd END),0) AS Service_tijd, 
    ISNULL(MIN(CASE WHEN Afdeling = 'CNC' THEN Orders END),0) AS Draaibank_ord,
    ISNULL(MIN(CASE WHEN Afdeling = 'CNC' THEN Tijd END),0) AS Draaibank_tijd, 
    ISNULL(MIN(CASE WHEN Afdeling = 'SECL' THEN Orders END),0) AS Bougiekabels_ord,
    ISNULL(MIN(CASE WHEN Afdeling = 'SECL' THEN Tijd END),0) AS Bougiekabels_tijd 
FROM [pp].dbo.VW_BEZETTING_RAW b1
GROUP BY Start

答案 1 :(得分:2)

试试这个 -

;WITH cte AS 
(
    SELECT 
          Orders
        , Tijd
        , Afdeling
        , Start 
    FROM dbo.VW_BEZETTING_RAW    
)
SELECT Start,
    ISNULL((SELECT Orders FROM cte b2 WHERE b2.Start=b1.Start AND Afdeling = 'WP'),0) AS Werkplaats_ord,
    ISNULL((SELECT Tijd FROM cte b2 WHERE b2.Start=b1.Start AND Afdeling = 'WP'),0) AS Werkplaats_tijd, 
    ISNULL((SELECT Orders FROM cte b2 WHERE b2.Start=b1.Start AND Afdeling = 'MAG'),0) AS Magazijn_ord,
    ISNULL((SELECT Tijd FROM cte b2 WHERE b2.Start=b1.Start AND Afdeling = 'MAG'),0) AS Magazijn_tijd, 
    ISNULL((SELECT Orders FROM cte b2 WHERE b2.Start=b1.Start AND Afdeling = 'SERV'),0) AS Service_ord,
    ISNULL((SELECT Tijd FROM cte b2 WHERE b2.Start=b1.Start AND Afdeling = 'SERV'),0) AS Service_tijd, 
    ISNULL((SELECT Orders FROM cte b2 WHERE b2.Start=b1.Start AND Afdeling = 'CNC'),0) AS Draaibank_ord,
    ISNULL((SELECT Tijd FROM cte b2 WHERE b2.Start=b1.Start AND Afdeling = 'CNC'),0) AS Draaibank_tijd, 
    ISNULL((SELECT Orders FROM cte b2 WHERE b2.Start=b1.Start AND Afdeling = 'SECL'),0) AS Bougiekabels_ord,
    ISNULL((SELECT Tijd FROM cte b2 WHERE b2.Start=b1.Start AND Afdeling = 'SECL'),0) AS Bougiekabels_tijd 
FROM cte b1
GROUP BY Start

或试试这个 -

SELECT 
    Start,
    Werkplaats_ord = MIN(CASE WHEN Afdeling = 'WP' THEN Orders ELSE 0 END) ,
    Werkplaats_tijd = MIN(CASE WHEN Afdeling = 'WP' THEN Tijd ELSE 0 END) , 
    Magazijn_ord = MIN(CASE WHEN Afdeling = 'MAG' THEN Orders ELSE 0 END) ,
    Magazijn_tijd = MIN(CASE WHEN Afdeling = 'MAG' THEN Tijd ELSE 0 END) , 
    Service_ord = MIN(CASE WHEN Afdeling = 'SERV' THEN Orders ELSE 0 END) ,
    Service_tijd = MIN(CASE WHEN Afdeling = 'SERV' THEN Tijd ELSE 0 END) , 
    Draaibank_ord = MIN(CASE WHEN Afdeling = 'CNC' THEN Orders ELSE 0 END) ,
    Draaibank_tijd = MIN(CASE WHEN Afdeling = 'CNC' THEN Tijd ELSE 0 END) , 
    Bougiekabels_ord = MIN(CASE WHEN Afdeling = 'SECL' THEN Orders ELSE 0 END) ,
    Bougiekabels_tijd = MIN(CASE WHEN Afdeling = 'SECL' THEN Tijd ELSE 0 END)  
FROM dbo.VW_BEZETTING_RAW b1
GROUP BY Start