【发布时间】:2018-03-08 11:12:32
【问题描述】:
我正在查询多个OUTER APPLY,但所有表在连接列上都有主键(因此此处使用聚集索引),所以我不知道如何进一步优化此查询。此外,这里也不可能使用索引视图,因为它们禁止使用ORDER BY 和TOP。
所以我有
表
Fields带有Id主键和大量其他列。WeatherHistory具有复杂主键(FieldId和[Date])和很多列的表,NdviImageHistory表与FieldId、[Date]、[Base64]列(复杂主键FieldId和[Date])其中[Base64]存储图像base64,NaturalColorImageHistory表与FieldId、[Date]、[Base64]列(复杂主键FieldId和[Date])其中[Base64]存储图像base64,NdviHistory表与FieldId、[Date]、MeanNdvi列(复杂主键FieldId和[Date]),FieldSeasonHistory表与Field、StartDate、EndDate列(复杂主键FieldId和[Date])。
我的查询
SELECT Fields.*,
WeatherHistory.TempSumC AS CurrentTempSumC,
TempSumF AS CurrentTempSumF,
PrecipitationSumMm AS CurrentPrecipitationSumMm,
nih.[Base64] AS CurrentNdviImageBase64,
ncih.[Base64] AS CurrentNaturalColorImageBase64,
MeanNdvi AS CurrentMeanNdvi,
IsOpenSeason
FROM Fields
LEFT JOIN WeatherHistory ON FieldId = Id AND [Date] = CAST(GETUTCDATE() AS DATE)
OUTER APPLY
(
SELECT TOP 1 [Base64]
FROM NdviImageHistory
WHERE FieldId = Id
ORDER BY [Date] DESC
) nih
OUTER APPLY
(
SELECT TOP 1 [Base64]
FROM NaturalColorImageHistory
WHERE FieldId = Id
ORDER BY [Date] DESC
) ncih
OUTER APPLY
(
SELECT TOP 1 MeanNdvi
FROM NdviHistory
WHERE FieldId = Id
ORDER BY [Date] DESC
) nh
OUTER APPLY
(
SELECT TOP 1 CASE WHEN EndDate IS NULL THEN 1 ELSE 0 END AS IsOpenSeason
FROM FieldSeasonHistory
WHERE FieldId = Id
ORDER BY [StartDate] DESC
) fsh
WHERE UserId = (SELECT Id FROM Users WHERE Email = @email) AND IsArchived = 0
我没有创建任何索引,因为我认为自动生成的集群索引(基于主键)应该足够了(但我可能是错的)。此查询执行大约 15 秒,但我想减少查询时间。
编辑:为Fields 表的UserId 和IsArchived 列添加了索引。查询执行计划:
** 编辑 2:** 统计:
SQL Server parse and compile time:
CPU time = 0 ms, elapsed time = 0 ms.
SQL Server Execution Times:
CPU time = 0 ms, elapsed time = 0 ms.
SQL Server parse and compile time:
CPU time = 0 ms, elapsed time = 0 ms.
SQL Server Execution Times:
CPU time = 0 ms, elapsed time = 0 ms.
SQL Server Execution Times:
CPU time = 0 ms, elapsed time = 0 ms.
SQL Server Execution Times:
CPU time = 0 ms, elapsed time = 0 ms.
(13 row(s) affected)
Table 'FieldSeasonHistory'. Scan count 13, logical reads 26, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'NdviHistory'. Scan count 13, logical reads 26, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'NaturalColorImageHistory'. Scan count 13, logical reads 26, physical reads 0, read-ahead reads 0, lob logical reads 604, lob physical reads 0, lob read-ahead reads 0.
Table 'NdviImageHistory'. Scan count 13, logical reads 39, physical reads 0, read-ahead reads 0, lob logical reads 68, lob physical reads 0, lob read-ahead reads 0.
Table 'WeatherHistory'. Scan count 0, logical reads 39, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'Users'. Scan count 0, logical reads 228, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'Fields'. Scan count 1, logical reads 19, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
(1 row(s) affected)
SQL Server Execution Times:
CPU time = 15 ms, elapsed time = 16 ms.
SQL Server parse and compile time:
CPU time = 0 ms, elapsed time = 0 ms.
SQL Server Execution Times:
CPU time = 0 ms, elapsed time = 0 ms.
【问题讨论】:
标签: sql sql-server query-optimization cross-apply outer-apply