Один и тот же запрос - разные планы выполнения

SQL 2008.
У меня есть тестовая таблица:

create table Sale
(
    SaleId int identity(1, 1)
        constraint PK_Sale primary key,
    Test1 varchar(10) null,
    RowVersion rowversion not null
        constraint UQ_Sale_RowVersion unique
)

Я заполняю ее 10 000 тестовых строк.

declare @RowCount int = 10000
while(@RowCount > 0)
begin
    insert Sale default values
    set @RowCount -= 1
end

Я выполняю эти два запроса:

-- Query #1

select *
from Sale
where RowVersion > 0x000000000001C310

-- Query #2

declare @LastVersion rowversion = 0x000000000001C310

select *
from Sale
where RowVersion > @LastVersion

Я не могу понять, почему эти два запроса имеют разный план выполнения.
Запрос №1 выполняет поиск индекса по индексу UQ_Sale_RowVersion.
Запрос №2 выполняет сканирование индекса по PK_Sale.

Я хочу, чтобы запрос №2 выполнял поиск по индексу.
Буду признателен за помощь.
Спасибо.

[Edit]

Пытался использовать datetime2 вместо rowversion. Та же проблема.

Я также попытался принудительно использовать индекс (запрос №3)

select *
from Sale with (index = IX_Sale_RowVersion)
where RowVersion > @LastVersion

Похоже, он показал тот же план выполнения запроса, что и запрос №1, но план выполнения показал, что этот запрос №3 является самым дорогим среди все эти 3 запроса.

[Edit] План выполнения:

<ShowPlanXML xmlns="http://schemas.microsoft.com/sqlserver/2004/07/showplan"
              Version="1.1"
              Build="10.50.1600.1">
  <BatchSequence>
    <Batch>
      <Statements>
        <StmtSimple StatementText="-- Query #1&#xd;&#xa;&#xd;&#xa;select *&#xd;&#xa;from Sale&#xd;&#xa;where RowVersion &gt; 0x000000000001C310&#xd;&#xa;&#xd;&#xa;-- Query #2&#xd;&#xa;&#xd;"
                    StatementId="1"
                    StatementCompId="1"
                    StatementType="SELECT"
                    StatementSubTreeCost="0.00657038"
                    StatementEstRows="1"
                    StatementOptmLevel="FULL"
                    QueryHash="0xE442FF9A4A2A630A"
                    QueryPlanHash="0x347569CFDEF2A13F"
                    StatementOptmEarlyAbortReason="GoodEnoughPlanFound"
                    ParameterizedText="(@1 varbinary(8000))SELECT * FROM [Sale] WHERE [RowVersion]&gt;@1">
          <StatementSetOptions QUOTED_IDENTIFIER="true"
                                ARITHABORT="true"
                                CONCAT_NULL_YIELDS_NULL="true"
                                ANSI_NULLS="true"
                                ANSI_PADDING="true"
                                ANSI_WARNINGS="true"
                                NUMERIC_ROUNDABORT="false"/>
          <QueryPlan CachedPlanSize="24"
                      CompileTime="1"
                      CompileCPU="1"
                      CompileMemory="136">
            <RelOp NodeId="0"
                    PhysicalOp="Nested Loops"
                    LogicalOp="Inner Join"
                    EstimateRows="1"
                    EstimateIO="0"
                    EstimateCPU="4.18e-006"
                    AvgRowSize="28"
                    EstimatedTotalSubtreeCost="0.00657038"
                    Parallel="0"
                    EstimateRebinds="0"
                    EstimateRewinds="0">
              <OutputList>
                <ColumnReference Database="[AdventureWorks]"
                                  Schema="[dbo]"
                                  Table="[Sale]"
                                  Column="SaleId"/>
                <ColumnReference Database="[AdventureWorks]"
                                  Schema="[dbo]"
                                  Table="[Sale]"
                                  Column="Test1"/>
                <ColumnReference Database="[AdventureWorks]"
                                  Schema="[dbo]"
                                  Table="[Sale]"
                                  Column="RowVersion"/>
              </OutputList>
              <NestedLoops Optimized="0">
                <OuterReferences>
                  <ColumnReference Database="[AdventureWorks]"
                                    Schema="[dbo]"
                                    Table="[Sale]"
                                    Column="SaleId"/>
                </OuterReferences>
                <RelOp NodeId="1"
                        PhysicalOp="Index Seek"
                        LogicalOp="Index Seek"
                        EstimateRows="1"
                        EstimateIO="0.003125"
                        EstimateCPU="0.0001581"
                        AvgRowSize="19"
                        EstimatedTotalSubtreeCost="0.0032831"
                        TableCardinality="10000"
                        Parallel="0"
                        EstimateRebinds="0"
                        EstimateRewinds="0">
                  <OutputList>
                    <ColumnReference Database="[AdventureWorks]"
                                      Schema="[dbo]"
                                      Table="[Sale]"
                                      Column="SaleId"/>
                    <ColumnReference Database="[AdventureWorks]"
                                      Schema="[dbo]"
                                      Table="[Sale]"
                                      Column="RowVersion"/>
                  </OutputList>
                  <IndexScan Ordered="1"
                              ScanDirection="FORWARD"
                              ForcedIndex="0"
                              ForceSeek="0"
                              NoExpandHint="0">
                    <DefinedValues>
                      <DefinedValue>
                        <ColumnReference Database="[AdventureWorks]"
                                          Schema="[dbo]"
                                          Table="[Sale]"
                                          Column="SaleId"/>
                      </DefinedValue>
                      <DefinedValue>
                        <ColumnReference Database="[AdventureWorks]"
                                          Schema="[dbo]"
                                          Table="[Sale]"
                                          Column="RowVersion"/>
                      </DefinedValue>
                    </DefinedValues>
                    <Object Database="[AdventureWorks]"
                            Schema="[dbo]"
                            Table="[Sale]"
                            Index="[UQ_Sale_RowVersion]"
                            IndexKind="NonClustered"/>
                    <SeekPredicates>
                      <SeekPredicateNew>
                        <SeekKeys>
                          <StartRange ScanType="GT">
                            <RangeColumns>
                              <ColumnReference Database="[AdventureWorks]"
                                                Schema="[dbo]"
                                                Table="[Sale]"
                                                Column="RowVersion"/>
                            </RangeColumns>
                            <RangeExpressions>
                              <ScalarOperator ScalarString="0x000000000001C310">
                                <Const ConstValue="0x000000000001C310"/>
                              </ScalarOperator>
                            </RangeExpressions>
                          </StartRange>
                        </SeekKeys>
                      </SeekPredicateNew>
                    </SeekPredicates>
                  </IndexScan>
                </RelOp>
                <RelOp NodeId="3"
                        PhysicalOp="Clustered Index Seek"
                        LogicalOp="Clustered Index Seek"
                        EstimateRows="1"
                        EstimateIO="0.003125"
                        EstimateCPU="0.0001581"
                        AvgRowSize="16"
                        EstimatedTotalSubtreeCost="0.0032831"
                        TableCardinality="10000"
                        Parallel="0"
                        EstimateRebinds="0"
                        EstimateRewinds="0">
                  <OutputList>
                    <ColumnReference Database="[AdventureWorks]"
                                      Schema="[dbo]"
                                      Table="[Sale]"
                                      Column="Test1"/>
                  </OutputList>
                  <IndexScan Lookup="1"
                              Ordered="1"
                              ScanDirection="FORWARD"
                              ForcedIndex="0"
                              ForceSeek="0"
                              NoExpandHint="0">
                    <DefinedValues>
                      <DefinedValue>
                        <ColumnReference Database="[AdventureWorks]"
                                          Schema="[dbo]"
                                          Table="[Sale]"
                                          Column="Test1"/>
                      </DefinedValue>
                    </DefinedValues>
                    <Object Database="[AdventureWorks]"
                            Schema="[dbo]"
                            Table="[Sale]"
                            Index="[PK_Sale]"
                            TableReferenceId="-1"
                            IndexKind="Clustered"/>
                    <SeekPredicates>
                      <SeekPredicateNew>
                        <SeekKeys>
                          <Prefix ScanType="EQ">
                            <RangeColumns>
                              <ColumnReference Database="[AdventureWorks]"
                                                Schema="[dbo]"
                                                Table="[Sale]"
                                                Column="SaleId"/>
                            </RangeColumns>
                            <RangeExpressions>
                              <ScalarOperator ScalarString="[AdventureWorks].[dbo].[Sale].[SaleId]">
                                <Identifier>
                                  <ColumnReference Database="[AdventureWorks]"
                                                    Schema="[dbo]"
                                                    Table="[Sale]"
                                                    Column="SaleId"/>
                                </Identifier>
                              </ScalarOperator>
                            </RangeExpressions>
                          </Prefix>
                        </SeekKeys>
                      </SeekPredicateNew>
                    </SeekPredicates>
                  </IndexScan>
                </RelOp>
              </NestedLoops>
            </RelOp>
            <ParameterList>
              <ColumnReference Column="@1"
                                ParameterCompiledValue="0x000000000001C310"/>
            </ParameterList>
          </QueryPlan>
        </StmtSimple>
              <StmtSimple StatementText="&#xa;declare @LastVersion rowversion = 0x000000000001C310&#xd;&#xa;&#xd;"
                  StatementId="2"
                  StatementCompId="2"
                  StatementType="ASSIGN"/>
        <StmtSimple StatementText="&#xa;select *&#xd;&#xa;from Sale&#xd;&#xa;where RowVersion &gt; @LastVersion"
                    StatementId="3"
                    StatementCompId="3"
                    StatementType="SELECT"
                    StatementSubTreeCost="0.0328005"
                    StatementEstRows="3000"
                    StatementOptmLevel="FULL"
                    QueryHash="0xE442FF9A4A2A630A"
                    QueryPlanHash="0x0C6238F821406F2B"
                    StatementOptmEarlyAbortReason="GoodEnoughPlanFound">
          <StatementSetOptions QUOTED_IDENTIFIER="true"
                                ARITHABORT="true"
                                CONCAT_NULL_YIELDS_NULL="true"
                                ANSI_NULLS="true"
                                ANSI_PADDING="true"
                                ANSI_WARNINGS="true"
                                NUMERIC_ROUNDABORT="false"/>
          <QueryPlan CachedPlanSize="16"
                      CompileTime="1"
                      CompileCPU="1"
                      CompileMemory="144">
            <RelOp NodeId="0"
                    PhysicalOp="Clustered Index Scan"
                    LogicalOp="Clustered Index Scan"
                    EstimateRows="3000"
                    EstimateIO="0.0216435"
                    EstimateCPU="0.011157"
                    AvgRowSize="28"
                    EstimatedTotalSubtreeCost="0.0328005"
                    TableCardinality="10000"
                    Parallel="0"
                    EstimateRebinds="0"
                    EstimateRewinds="0">
              <OutputList>
                <ColumnReference Database="[AdventureWorks]"
                                  Schema="[dbo]"
                                  Table="[Sale]"
                                  Column="SaleId"/>
                <ColumnReference Database="[AdventureWorks]"
                                  Schema="[dbo]"
                                  Table="[Sale]"
                                  Column="Test1"/>
                <ColumnReference Database="[AdventureWorks]"
                                  Schema="[dbo]"
                                  Table="[Sale]"
                                  Column="RowVersion"/>
              </OutputList>
              <IndexScan Ordered="0"
                          ForcedIndex="0"
                          NoExpandHint="0">
                <DefinedValues>
                  <DefinedValue>
                    <ColumnReference Database="[AdventureWorks]"
                                      Schema="[dbo]"
                                      Table="[Sale]"
                                      Column="SaleId"/>
                  </DefinedValue>
                  <DefinedValue>
                    <ColumnReference Database="[AdventureWorks]"
                                      Schema="[dbo]"
                                      Table="[Sale]"
                                      Column="Test1"/>
                  </DefinedValue>
                  <DefinedValue>
                    <ColumnReference Database="[AdventureWorks]"
                                      Schema="[dbo]"
                                      Table="[Sale]"
                                      Column="RowVersion"/>
                  </DefinedValue>
                </DefinedValues>
                <Object Database="[AdventureWorks]"
                        Schema="[dbo]"
                        Table="[Sale]"
                        Index="[PK_Sale]"
                        IndexKind="Clustered"/>
                <Predicate>
                  <ScalarOperator ScalarString="[AdventureWorks].[dbo].[Sale].[RowVersion]&gt;[@LastVersion]">
                    <Compare CompareOp="GT">
                      <ScalarOperator>
                        <Identifier>
                          <ColumnReference Database="[AdventureWorks]"
                                            Schema="[dbo]"
                                            Table="[Sale]"
                                            Column="RowVersion"/>
                        </Identifier>
                      </ScalarOperator>
                      <ScalarOperator>
                        <Identifier>
                          <ColumnReference Column="@LastVersion"/>
                        </Identifier>
                      </ScalarOperator>
                    </Compare>
                  </ScalarOperator>
                </Predicate>
              </IndexScan>
            </RelOp>
          </QueryPlan>
        </StmtSimple>
      </Statements>
    </Batch>
  </BatchSequence>
</ShowPlanXML>
9
задан Alex Aza 20 May 2011 в 15:10
поделиться