我有一个在sql Server 2008上运行的小sql查询。它使用以下表及其行计数:
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
基本上,如果不查看实际的表设计和索引,很难确切地告诉您需要更改哪些内容。但对于初学者,您绝对可以考虑两件事:
-
在您的
CTE_CONS
查询中,您正在对Datetime
字段进行左连接。这绝对不是一个好主意,除非你在那个字段上有某种索引。如果还没有索引,我强烈建议您创建一个。CREATE NONCLUSTERED INDEX IX_UTC_DATETIME ON dbo.ers_hh_forecast_consumption (UTC_DATETIME ASC) INCLUDE ( FORECAST_FILE_ID ,FORECAST_CONSUMPTION );
-
您可以考虑做的另一件事是对表
dbo.ers_hh_forecast_consumption
进行分区。这样一来,读取的时间就少了,检索记录的速度也快了很多。下面是如何决定是否应该使用表分区的快速指南。
希望这对你有帮助!
除了你需要提供更多的信息让我们更好地了解正在发生的事情这一事实之外,我认为我在这里发现了你的查询的一个问题:
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()
每个T2.CONVERTED_DATE ,T1.FORECAST_FILE_ID
组合的T1.FORECAST_CONSUMPTION
的值。但是,在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)。