我有一个存储过程,我不久前编写了它来帮助生成一个 XML 文件,该文件将用于与外部资源共享数据。基本上,最终用户将数据转储到一个名为 DataSharing 的表中,然后当我们执行查询时,它将返回一个 XML 文档,其中包含在 DataSharing 中指定的所需字段。现在这个程序运行良好,但是速度非常慢。当我通过 SSMS 运行它并设置“显示实际执行计划”时,94% 的查询都用于索引假脱机(急切假脱机)。经过研究,我似乎应该重新设计查询以更好地执行。
由于数据的列我永远不知道它们是什么,所以我必须做独特的数据透视才能生成我的数据。
这是程序:
CREATE PROCEDURE [dbo].[sp_HPSDDataSharing]
-- Add the parameters for the stored procedure here
@fileName varchar(MAX), @StartDate datetime, @EndDate datetime
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
DECLARE @sqlCommand varchar(MAX), @listStr VARCHAR(MAX)
SELECT @listStr =
COALESCE(@listStr +',' ,'') + '[' + [ColumnName] + ']'
FROM [FCPP_HPSD].[dbo].[DataSharing]
WHERE FileName = @fileName
DECLARE @Result XML
SET @sqlCommand = 'Select * From ( SELECT
[DatapointDate]
,dp.ColumnName
,[DataPointValue]
FROM [FCPP_HPSD].[dbo].[vw_DataCollection] DC
JOIN [FCPP_HPSD].[dbo].[Datasharing] dp
ON DC.DataPointID = DP.DatapointID
WHERE
[DatapointDate] >= ''' + CONVERT(varchar(MAX), @StartDate) + '''
and [DatapointDate] < ''' + CONVERT(varchar(MAX), @EndDate) + '''
and dc.DataPointID in (SELECT [DatapointID] FROM [FCPP_HPSD].[dbo].[DataSharing] Where FileName = ''' + @fileName + ''')
) AS source
PIVOT
(
SUM(DataPointValue)
FOR ColumnName IN ('+ @listStr +')
) as pvt
ORDER BY DatapointDate
FOR XML Path(''' + 'DataRow' + '''), ROOT;'
Print @sqlCommand
EXEC (@sqlCommand)
END
GO
完全执行的查询如下所示:
SELECT *
FROM (SELECT [datapointdate],
dp.columnname,
[datapointvalue]
FROM [FCPP_HPSD].[dbo].[vw_datacollection] DC
JOIN [FCPP_HPSD].[dbo].[datasharing] dp
ON DC.datapointid = DP.datapointid
WHERE [datapointdate] >= 'Jul 15 2013 12:00AM'
AND [datapointdate] < 'Jul 22 2013 12:00AM'
AND dc.datapointid IN (SELECT [datapointid]
FROM [FCPP_HPSD].[dbo].[datasharing]
WHERE filename = 'fdrD3')) AS source
PIVOT ( Sum(datapointvalue)
FOR columnname IN ([fdrD3_kWh_A],
[fdrD3_kWh_B],
[fdrD3_kWh_C],
[fdrD3_kWh],
[fdrD3_I_A],
[fdrD3_I_B],
[fdrD3_I_C],
[fdrD3_I_N],
[fdrD3_V_A],
[fdrD3_V_B],
[fdrD3_V_C],
[fdrD3_V_A-B],
[fdrD3_V_B-C],
[fdrD3_kV_C-A],
[fdrD3_kW],
[fdrD3_kVA],
[fdrD3_kVAr],
[fdrD3_kW_A],
[fdrD3_kW_B],
[fdrD3_kW_C],
[fdrD3_kVA_A],
[fdrD3_kVA_B],
[fdrD3_kVA_C],
[fdrD3_kVAr_A],
[fdrD3_kVAr_B],
[fdrD3_kVAr_C],
[fdrD3_F],
[fdrD3_Iang_A],
[fdrD3_Iang_B],
[fdrD3_Iang_C],
[fdrD3_Iang_N],
[fdrD3_Vang_A],
[fdrD3_Vang_B],
[fdrD3_Vang_C],
[fdrD3_Vang_A-B],
[fdrD3_Vang_B-C],
[fdrD3_Vang_C-A],
[fdrD3_PF_A],
[fdrD3_PF_B],
[fdrD3_PF_C],
[fdrD3_PF],
[fdrD3_Pst_V_A],
[fdrD3_Pst_V_B],
[fdrD3_Pst_V_C],
[fdrD3_Plt_V_A],
[fdrD3_Plt_V_B],
[fdrD3_Plt_V_C],
[fdrD3_Vdev_A],
[fdrD3_Vdev_B],
[fdrD3_Vdev_C],
[fdrD3_Fdev],
[fdrD3_THD_I_A],
[fdrD3_THD_I_B],
[fdrD3_THD_I_C],
[fdrD3_THD_I_N],
[fdrD3_THD_V_A],
[fdrD3_THD_V_B],
[fdrD3_THD_V_C]) ) AS pvt
ORDER BY datapointdate
FOR xml path('DataRow'), root;
因此,当前程序当前需要 35-65 秒才能运行。在处理超时时,我真的需要了解加快此过程的速度。如果有人可以帮助我,我可以做些什么来帮助加快速度并摆脱在 Index Spool(eager spool)上花费的大量时间,我将不胜感激。
编辑1:
我添加了一个SQL Fiddle所以希望这会有所帮助。