外部リソースとデータを共有するために使用される XML ファイルを生成するために、しばらく前に作成したストアド プロシージャがあります。基本的に、エンド ユーザーは DataSharing と呼ばれるテーブル内にデータをダンプします。クエリを実行すると、DataSharing 内で指定された必須フィールドを含む XML ドキュメントが返されます。現在、この手順はうまく機能していますが、非常に遅いです。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を追加したので、これが役立つことを願っています。