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)。