0

我有一個SQL Server 2008上運行,它使用下面的表和他們的行數小的SQL查詢:查詢優化2008

dbo.date_master - 245424 
dbo.ers_hh_forecast_consumption - 436061472 
dbo.ers_hh_forecast_file - 15105 
dbo.ers_ed_supply_point - 8485 

我很新的SQL Server的世界,正在學習。請指導我如何能夠優化此查詢以更快地運行。

如果有人能夠提及我的錯誤以及我正在做什麼使得查詢生成的表格非常耗時,我將非常高興。

WITH CTE_CONS AS 
(
    SELECT T2.CONVERTED_DATE 
      ,T1.FORECAST_FILE_ID 
      ,SUM(T1.FORECAST_CONSUMPTION) AS TOTAL 
    FROM dbo.ers_hh_forecast_consumption AS T1 
    LEFT JOIN dbo.date_master AS T2 ON T1.UTC_DATETIME=T2.STRDATETIME 
    WHERE T2.CONVERTED_DATE>='2015-01-01' AND T2.CONVERTED_DATE<='2015-06-01' 
    GROUP BY T2.CONVERTED_DATE, T1.FORECAST_FILE_ID, T1.FORECAST_CONSUMPTION 
), 
CTE_MPAN AS 
(
    SELECT T2.FORECAST_FILE_ID 
      ,T2.MPAN_CORE 
    FROM CTE_CONS AS T1 
    LEFT JOIN dbo.ers_hh_forecast_file AS T2 ON T1.FORECAST_FILE_ID=T2.FORECAST_FILE_ID 
), 
CTE_GSP AS 
(
    SELECT T2.MPAN_CORE 
      ,T2.GSP_GROUP_ID 
    FROM CTE_MPAN AS T1 
    LEFT JOIN dbo.ers_ed_supply_point AS T2 ON T1.MPAN_CORE=T2.MPAN_CORE 
) 

SELECT T1.CONVERTED_DATE 
     ,T1.TOTAL 
     ,T2.MPAN_CORE 
     ,T1.TOTAL 
FROM CTE_CONS AS T1 
LEFT JOIN CTE_MPAN AS T2 ON T1.FORECAST_FILE_ID=T2.FORECAST_FILE_ID 
LEFT JOIN CTE_GSP AS T3 ON T2.MPAN_CORE=T3.MPAN_CORE 
+0

由於表「ers_hh_forecast_consumption」有大量記錄,最好使用過濾器條件將所需記錄插入到臨時表中,並在CTE中使用該臨時表。 –

+0

您是否有任何表的索引,例如預測消耗表的UTC_DATETIME索引。顯示錶格定義和索引將幫助你得到一個體面的答案。 –

+2

當我們不知道存在哪些指標時,很難提供建議。同時,您可以使用SSMS查看查詢的執行計劃以確定優化。 – Greg

回答

0

基本上,沒有看實際的表設計和指數,很難準確地告訴你需要改變什麼。但是對於初學者來說,你肯定可以考慮兩件事情:

  1. 在你CTE_CONS查詢,你正在做一個左連接上Datetime場。這絕對不是一個好主意,除非你在該領域有某種類型的索引。如果還沒有人,我強烈建議你創建一個索引。

    CREATE NONCLUSTERED INDEX IX_UTC_DATETIME ON dbo.ers_hh_forecast_consumption 
    (UTC_DATETIME ASC) INCLUDE (
    FORECAST_FILE_ID 
    ,FORECAST_CONSUMPTION 
    ); 
    
  2. ,你可以考慮做其他的事情,會被你的分區表dbo.ers_hh_forecast_consumption。這樣,您的閱讀在桌面上就會少得多,並且更快地檢索記錄。這裏是一個快速指南How To Decide if You Should Use Table Partitioning.

希望這有助於!

+0

謝謝新秀。我會嘗試兩個。 – Ravi

0

除了事實,你將需要提供相當多的信息讓我們獲得對正在發生的事情是個好主意,我想我發現了一個有點問題與您的查詢這裏:

WITH CTE_CONS AS 
(
    SELECT T2.CONVERTED_DATE 
      ,T1.FORECAST_FILE_ID 
      ,SUM(T1.FORECAST_CONSUMPTION) AS TOTAL 
    FROM dbo.ers_hh_forecast_consumption AS T1 
    LEFT JOIN dbo.date_master AS T2 ON T1.UTC_DATETIME=T2.STRDATETIME 
    WHERE T2.CONVERTED_DATE>='2015-01-01' AND T2.CONVERTED_DATE<='2015-06-01' 
    GROUP BY T2.CONVERTED_DATE, T1.FORECAST_FILE_ID, T1.FORECAST_CONSUMPTION 
) 

首先,你試圖SUM()的值爲T1.FORECAST_CONSUMPTIONT2.CONVERTED_DATE ,T1.FORECAST_FILE_ID的組合。但是,在GROUP BY中,您還會再次添加T1.FORECAST_CONSUMPTION?這與在三個字段上執行DISTINCT具有完全相同的效果。您可以從GROUP BY中刪除您從SUM()中刪除的字段,也可以使用DISTINCT並刪除SUM()GROUP BY;取決於你之後的效果。所涉及的所有表

  • EXEC sp_helpindex <table_name>

    無論如何,您可以加入下面的東西你的問題。

  • 如果可能的話,Execution Plan的屏幕截圖(來自SSMS或SQL Sentry Plan Explorer)。