使用多个OUTER APPLY优化查询

时间:2018-03-08 11:12:32

标签: sql sql-server query-optimization cross-apply outer-apply

我正在使用多个OUTER APPLY进行查询,但所有表都在已连接的列上具有主键(因此这里使用了聚簇索引),因此我不知道如何进一步优化此查询。此处也无法使用索引视图,因为禁止使用ORDER BYTOP

所以我有

  • Fields包含Id主键和各种其他列。

  • WeatherHistory表包含复杂的主键(FieldId[Date])以及许多列,

  • NdviImageHistory表格FieldId[Date][Base64]列(复杂主键FieldId[Date])其中{{ 1}}存储图像base64,

  • [Base64]表格NaturalColorImageHistoryFieldId[Date]列(复杂主键[Base64]FieldId)其中{{ 1}}存储图像base64,

  • [Date]表包含[Base64]NdviHistoryFieldId列(复杂主键[Date]MeanNdvi),< / p>

  • FieldId表包含[Date]FieldSeasonHistoryField列(复杂主键StartDateEndDate)。

我的查询

FieldId

我还没有创建任何索引,因为我认为自动生成的clusted索引(基于主键)应该足够(但我可能是错的)。此查询执行大约15秒,但我想减少查询时间。

修改:为[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 UserId列添加了索引。查询执行计划:

enter image description here

**编辑2:**统计:

IsArchived

2 个答案:

答案 0 :(得分:1)

您需要为每个表提供多列索引。索引应该是order by中的列,列select中的列,然后是NdviImageHistory(FieldId, [Date], [Base64])中的列。例如:

  • NaturalColorImageHistory(FieldId, [Date], [Base64])
  • export default class LineChartPresentational extends React.Component { constructor(props) { super(); this.state = { isclicked: true, }} changeStrokeclick() { this.setState({isclicked: !this.state.isclicked} )} render() { let strokecolor = this.state.isclicked ? "#9da0a5" : "#2d75ed" return ( <div> <div id="lclastdataref" style={{ textAlign: 'right' }}> <span>Last Data Refresh: {linechartdf.date} </span> </div> <div className='line-charts'> <div className="line-chart-wrapper " style={{ width: window.innerWidth / 2, height: window.innerHeight / 2, }}> <ResponsiveContainer> <LineChart width={width} height={height} margin={{ top: 20, right: 20, bottom: 20, left: 20 }} data={linechartdata} id="Line-Chart"> <XAxis dataKey={xAxisColumn} /> <YAxis domain={['auto', 'auto']} /> <Tooltip cursor={false} /> { linechartdata.map((entry, index) => ( <Line stroke={strokecolor} onClick={this.changeStrokeclick.bind(this)} name={linechartdata[index].dataKey} strokeWidth={lineThickness} dataKey={`value${index + 1}`} dot={false} className={`value${index + 1}`}/> )) } </LineChart> </ResponsiveContainer> </div> </div> </div> ); }
  • 等等。

答案 1 :(得分:-1)

像这样更新您的查询。

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 MAX(NdviImageHistory.ID) MAX_ID
    FROM NdviImageHistory
    WHERE FieldId = Id

) nih_ID
OUTER APPLY
(
    SELECT [Base64] FROM NdviImageHistory X WHERE X.ID = nih_ID.MAX_ID
)nih

用户更多外部申请所有这些表{nih,ncih,nh,fsh} 试试这个。

我只使用1个外部[nih]

从OUTER APPLY Joins中删除TOP 1和Order by