У меня есть продолжительный запрос SQL Server 2005 года, который я надеялся оптимизировать.
То, когда я смотрю на фактический план выполнения, он говорит, что Кластерный индекс Ищет, имеет 66% стоимости.
План Execuation Snippit:
<RelOp AvgRowSize="31" EstimateCPU="0.0113754" EstimateIO="0.0609028" EstimateRebinds="0" EstimateRewinds="0" EstimateRows="10198.5" LogicalOp="Clustered Index Seek" NodeId="16" Parallel="false" PhysicalOp="Clustered Index Seek" EstimatedTotalSubtreeCost="0.0722782">
<OutputList>
<ColumnReference Database="[wf_1]" Schema="[dbo]" Table="[Indices]" Alias="[I]" Column="quoteDate" />
<ColumnReference Database="[wf_1]" Schema="[dbo]" Table="[Indices]" Alias="[I]" Column="price" />
<ColumnReference Database="[wf_1]" Schema="[dbo]" Table="[Indices]" Alias="[I]" Column="tenure" />
</OutputList>
<RunTimeInformation>
<RunTimeCountersPerThread Thread="0" ActualRows="1067" ActualEndOfScans="1" ActualExecutions="1" />
</RunTimeInformation>
<IndexScan Ordered="true" ScanDirection="FORWARD" ForcedIndex="false" NoExpandHint="false">
<DefinedValues>
<DefinedValue>
<ColumnReference Database="[wf_1]" Schema="[dbo]" Table="[Indices]" Alias="[I]" Column="quoteDate" />
</DefinedValue>
<DefinedValue>
<ColumnReference Database="[wf_1]" Schema="[dbo]" Table="[Indices]" Alias="[I]" Column="price" />
</DefinedValue>
<DefinedValue>
<ColumnReference Database="[wf_1]" Schema="[dbo]" Table="[Indices]" Alias="[I]" Column="tenure" />
</DefinedValue>
</DefinedValues>
<Object Database="[wf_1]" Schema="[dbo]" Table="[Indices]" Index="[_dta_index_Indices_14_320720195__K5_K2_K1_3]" Alias="[I]" />
<SeekPredicates>
<SeekPredicate>
<Prefix ScanType="EQ">
<RangeColumns>
<ColumnReference Database="[wf_1]" Schema="[dbo]" Table="[Indices]" Alias="[I]" Column="HedgeProduct" ComputedColumn="true" />
</RangeColumns>
<RangeExpressions>
<ScalarOperator ScalarString="(1)">
<Const ConstValue="(1)" />
</ScalarOperator>
</RangeExpressions>
</Prefix>
<StartRange ScanType="GE">
<RangeColumns>
<ColumnReference Database="[wf_1]" Schema="[dbo]" Table="[Indices]" Alias="[I]" Column="tenure" />
</RangeColumns>
<RangeExpressions>
<ScalarOperator ScalarString="[@StartMonth]">
<Identifier>
<ColumnReference Column="@StartMonth" />
</Identifier>
</ScalarOperator>
</RangeExpressions>
</StartRange>
<EndRange ScanType="LE">
<RangeColumns>
<ColumnReference Database="[wf_1]" Schema="[dbo]" Table="[Indices]" Alias="[I]" Column="tenure" />
</RangeColumns>
<RangeExpressions>
<ScalarOperator ScalarString="[@EndMonth]">
<Identifier>
<ColumnReference Column="@EndMonth" />
</Identifier>
</ScalarOperator>
</RangeExpressions>
</EndRange>
</SeekPredicate>
</SeekPredicates>
</IndexScan>
</RelOp>
От этого кто-либо видит очевидную проблему, которая заставила бы это занимать много времени?
Вот запрос:
(SELECT quotedate, tenure, price, ActualVolume, HedgePortfolioValue, Price AS UnhedgedPrice, ((ActualVolume*Price - HedgePortfolioValue)/ActualVolume) AS HedgedPrice
FROM
(
SELECT [quoteDate]
,[price]
, tenure
,isnull(wf_1.[Risks].[HedgePortValueAsOfDate2](1,tenureMonth,quotedate,price),0) as HedgePortfolioValue
,[TotalOperatingGasVolume] as ActualVolume
FROM [wf_1].[dbo].[Indices] I
inner join
(
SELECT DISTINCT tenureMonth
FROM [wf_1].[Risks].[KnowRiskTrades]
WHERE HedgeProduct = 1
AND portfolio <> 'Natural Gas Hedge Transactions'
) B ON I.tenure=B.tenureMonth
inner join
(
SELECT [Month],[TotalOperatingGasVolume]
FROM [wf_1].[Risks].[ActualGasVolumes]
) C ON C.[Month]=B.tenureMonth
WHERE HedgeProduct = 1
AND quoteDate>=dateadd(day, -3*365, tenureMonth)
AND quoteDate<=dateadd(day,-3,tenureMonth)
)A
)
Этот бит вызывает сомнение, есть ли у вас индекс в портфеле? Почему вы используете DISTINCT?
SELECT DISTINCT tenureMonth
FROM [wf_1].[Risks].[KnowRiskTrades]
WHERE HedgeProduct = 1
AND portfolio <> 'Natural Gas Hedge Transactions'
Так же как и это:
WHERE HedgeProduct = 1
AND quoteDate>=dateadd(day, -3*365, tenureMonth)
AND quoteDate<=dateadd(day,-3,tenureMonth)
Но трудно дать хороший совет, не зная, где находятся индексы и сколько данных в соответствующих таблицах.
Также: Сколько времени занимает запрос? Как долго вы хотите, чтобы он выполнялся? Как часто вы его выполняете? Насколько загружен ваш сервер базы данных?
Похоже, у вас отключена статистика.
Этот запрос убивает мне глаза, и я не хочу угадывать и выбирать неправильную таблицу. Итак, в какую бы таблицу ни попадал CI-поиск, обновите статистику по крайней мере для этой таблицы и снова проверьте запрос.
ОБНОВЛЕНИЕ СТАТИСТИКИ: http://msdn.microsoft.com/en-us/library/ms187348.aspx