2016-10-28 41 views
8

我創建了以下索引來覆蓋select top語句。然而,它仍然需要一段時間(我的桌上有19萬秒,有5000萬行),執行計劃顯示仍然存在「排序」?爲什麼選擇top ... order by indexed column仍然排序?

執行規劃顯示

選擇(成本:0%)←頂(成本:0%)←並行(收集流)(成本:0%)←排序(前N個排序)成本: 93%←索引掃描(非聚集)[T.ix_]成本:7%


執行計劃

<?xml version="1.0" encoding="utf-16"?> 
<ShowPlanXML xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" Version="1.2" Build="12.0.4100.1" xmlns="http://schemas.microsoft.com/sqlserver/2004/07/showplan"> 
    <BatchSequence> 
    <Batch> 
     <Statements> 
     <StmtSimple StatementCompId="1" StatementEstRows="20" StatementId="1" StatementOptmLevel="FULL" CardinalityEstimationModelVersion="120" StatementSubTreeCost="552.009" StatementText="select top 20 A A, B B --, checksum(*) cs&#xA;from T with (index(ix_))&#xA;order by A, B" StatementType="SELECT" QueryHash="0x1531573504856080" QueryPlanHash="0x5D4FED760C34AF43" RetrievedFromCache="true"> 
      <StatementSetOptions ANSI_NULLS="true" ANSI_PADDING="true" ANSI_WARNINGS="true" ARITHABORT="true" CONCAT_NULL_YIELDS_NULL="true" NUMERIC_ROUNDABORT="false" QUOTED_IDENTIFIER="true" /> 
      <QueryPlan DegreeOfParallelism="8" MemoryGrant="1024" CachedPlanSize="24" CompileTime="2" CompileCPU="2" CompileMemory="256"> 
      <ThreadStat Branches="1" UsedThreads="8"> 
       <ThreadReservation NodeId="0" ReservedThreads="8" /> 
      </ThreadStat> 
      <MemoryGrantInfo SerialRequiredMemory="16" SerialDesiredMemory="24" RequiredMemory="896" DesiredMemory="960" RequestedMemory="1024" GrantWaitTime="0" GrantedMemory="1024" MaxUsedMemory="896" /> 
      <OptimizerHardwareDependentProperties EstimatedAvailableMemoryGrant="768000" EstimatedPagesCached="768000" EstimatedAvailableDegreeOfParallelism="8" /> 
      <RelOp AvgRowSize="15" EstimateCPU="2E-06" EstimateIO="0" EstimateRebinds="0" EstimateRewinds="0" EstimatedExecutionMode="Row" EstimateRows="20" LogicalOp="Top" NodeId="0" Parallel="false" PhysicalOp="Top" EstimatedTotalSubtreeCost="552.009"> 
       <OutputList> 
       <ColumnReference Database="[DB]" Schema="[dbo]" Table="[T]" Alias="[T]" Column="B" /> 
       <ColumnReference Database="[DB]" Schema="[dbo]" Table="[T]" Alias="[T]" Column="A" /> 
       </OutputList> 
       <RunTimeInformation> 
       <RunTimeCountersPerThread Thread="0" ActualRows="20" ActualEndOfScans="1" ActualExecutions="1" /> 
       </RunTimeInformation> 
       <Top RowCount="false" IsPercent="false" WithTies="false"> 
       <TopExpression> 
        <ScalarOperator ScalarString="(20)"> 
        <Const ConstValue="(20)" /> 
        </ScalarOperator> 
       </TopExpression> 
       <RelOp AvgRowSize="15" EstimateCPU="0.0286101" EstimateIO="0" EstimateRebinds="0" EstimateRewinds="0" EstimatedExecutionMode="Row" EstimateRows="20" LogicalOp="Gather Streams" NodeId="1" Parallel="true" PhysicalOp="Parallelism" EstimatedTotalSubtreeCost="552.009"> 
        <OutputList> 
        <ColumnReference Database="[DB]" Schema="[dbo]" Table="[T]" Alias="[T]" Column="B" /> 
        <ColumnReference Database="[DB]" Schema="[dbo]" Table="[T]" Alias="[T]" Column="A" /> 
        </OutputList> 
        <RunTimeInformation> 
        <RunTimeCountersPerThread Thread="0" ActualRows="20" ActualEndOfScans="0" ActualExecutions="1" /> 
        </RunTimeInformation> 
        <Parallelism> 
        <OrderBy> 
         <OrderByColumn Ascending="true"> 
         <ColumnReference Database="[DB]" Schema="[dbo]" Table="[T]" Alias="[T]" Column="A" /> 
         </OrderByColumn> 
         <OrderByColumn Ascending="true"> 
         <ColumnReference Database="[DB]" Schema="[dbo]" Table="[T]" Alias="[T]" Column="B" /> 
         </OrderByColumn> 
        </OrderBy> 
        <RelOp AvgRowSize="15" EstimateCPU="212.739" EstimateIO="303.269" EstimateRebinds="0" EstimateRewinds="0" EstimatedExecutionMode="Row" EstimateRows="20" LogicalOp="TopN Sort" NodeId="2" Parallel="true" PhysicalOp="Sort" EstimatedTotalSubtreeCost="551.98"> 
         <OutputList> 
         <ColumnReference Database="[DB]" Schema="[dbo]" Table="[T]" Alias="[T]" Column="B" /> 
         <ColumnReference Database="[DB]" Schema="[dbo]" Table="[T]" Alias="[T]" Column="A" /> 
         </OutputList> 
         <MemoryFractions Input="1" Output="1" /> 
         <RunTimeInformation> 
         <RunTimeCountersPerThread Thread="8" ActualRebinds="1" ActualRewinds="0" ActualRows="12" Batches="0" ActualEndOfScans="0" ActualExecutions="1" ActualExecutionMode="Row" /> 
         <RunTimeCountersPerThread Thread="3" ActualRebinds="1" ActualRewinds="0" ActualRows="12" Batches="0" ActualEndOfScans="0" ActualExecutions="1" ActualExecutionMode="Row" /> 
         <RunTimeCountersPerThread Thread="7" ActualRebinds="1" ActualRewinds="0" ActualRows="12" Batches="0" ActualEndOfScans="0" ActualExecutions="1" ActualExecutionMode="Row" /> 
         <RunTimeCountersPerThread Thread="6" ActualRebinds="1" ActualRewinds="0" ActualRows="20" Batches="0" ActualEndOfScans="1" ActualExecutions="1" ActualExecutionMode="Row" /> 
         <RunTimeCountersPerThread Thread="5" ActualRebinds="1" ActualRewinds="0" ActualRows="12" Batches="0" ActualEndOfScans="0" ActualExecutions="1" ActualExecutionMode="Row" /> 
         <RunTimeCountersPerThread Thread="4" ActualRebinds="1" ActualRewinds="0" ActualRows="12" Batches="0" ActualEndOfScans="0" ActualExecutions="1" ActualExecutionMode="Row" /> 
         <RunTimeCountersPerThread Thread="2" ActualRebinds="1" ActualRewinds="0" ActualRows="12" Batches="0" ActualEndOfScans="0" ActualExecutions="1" ActualExecutionMode="Row" /> 
         <RunTimeCountersPerThread Thread="1" ActualRebinds="1" ActualRewinds="0" ActualRows="12" Batches="0" ActualEndOfScans="0" ActualExecutions="1" ActualExecutionMode="Row" /> 
         <RunTimeCountersPerThread Thread="0" ActualRebinds="0" ActualRewinds="0" ActualRows="0" ActualEndOfScans="0" ActualExecutions="0" /> 
         </RunTimeInformation> 
         <TopSort Distinct="false" Rows="20"> 
         <OrderBy> 
          <OrderByColumn Ascending="true"> 
          <ColumnReference Database="[DB]" Schema="[dbo]" Table="[T]" Alias="[T]" Column="A" /> 
          </OrderByColumn> 
          <OrderByColumn Ascending="true"> 
          <ColumnReference Database="[DB]" Schema="[dbo]" Table="[T]" Alias="[T]" Column="B" /> 
          </OrderByColumn> 
         </OrderBy> 
         <RelOp AvgRowSize="15" EstimateCPU="5.81245" EstimateIO="30.16" EstimateRebinds="0" EstimateRewinds="0" EstimatedExecutionMode="Row" EstimateRows="42226500" LogicalOp="Index Scan" NodeId="3" Parallel="true" Partitioned="true" PhysicalOp="Index Scan" EstimatedTotalSubtreeCost="35.9724" TableCardinality="42226500"> 
          <OutputList> 
          <ColumnReference Database="[DB]" Schema="[dbo]" Table="[T]" Alias="[T]" Column="B" /> 
          <ColumnReference Database="[DB]" Schema="[dbo]" Table="[T]" Alias="[T]" Column="A" /> 
          </OutputList> 
          <RunTimeInformation> 
          <RunTimeCountersPerThread Thread="8" ActualRows="3993270" Batches="0" ActualEndOfScans="1" ActualExecutions="1" ActualExecutionMode="Row" /> 
          <RunTimeCountersPerThread Thread="7" ActualRows="2713924" Batches="0" ActualEndOfScans="1" ActualExecutions="1" ActualExecutionMode="Row" /> 
          <RunTimeCountersPerThread Thread="6" ActualRows="8866373" Batches="0" ActualEndOfScans="1" ActualExecutions="1" ActualExecutionMode="Row" /> 
          <RunTimeCountersPerThread Thread="5" ActualRows="10625143" Batches="0" ActualEndOfScans="1" ActualExecutions="1" ActualExecutionMode="Row" /> 
          <RunTimeCountersPerThread Thread="4" ActualRows="4254726" Batches="0" ActualEndOfScans="1" ActualExecutions="1" ActualExecutionMode="Row" /> 
          <RunTimeCountersPerThread Thread="3" ActualRows="3195887" Batches="0" ActualEndOfScans="1" ActualExecutions="1" ActualExecutionMode="Row" /> 
          <RunTimeCountersPerThread Thread="2" ActualRows="3626671" Batches="0" ActualEndOfScans="1" ActualExecutions="1" ActualExecutionMode="Row" /> 
          <RunTimeCountersPerThread Thread="1" ActualRows="4950538" Batches="0" ActualEndOfScans="1" ActualExecutions="1" ActualExecutionMode="Row" /> 
          <RunTimeCountersPerThread Thread="0" ActualRows="0" ActualEndOfScans="0" ActualExecutions="0" /> 
          </RunTimeInformation> 
          <RunTimePartitionSummary> 
          <PartitionsAccessed PartitionCount="41"> 
           <PartitionRange Start="1" End="41" /> 
          </PartitionsAccessed> 
          </RunTimePartitionSummary> 
          <IndexScan Ordered="false" ForcedIndex="true" ForceSeek="false" ForceScan="false" NoExpandHint="false" Storage="RowStore"> 
          <DefinedValues> 
           <DefinedValue> 
           <ColumnReference Database="[DB]" Schema="[dbo]" Table="[T]" Alias="[T]" Column="B" /> 
           </DefinedValue> 
           <DefinedValue> 
           <ColumnReference Database="[DB]" Schema="[dbo]" Table="[T]" Alias="[T]" Column="A" /> 
           </DefinedValue> 
          </DefinedValues> 
          <Object Database="[DB]" Schema="[dbo]" Table="[T]" Index="[ix_]" Alias="[T]" IndexKind="NonClustered" Storage="RowStore" /> 
          </IndexScan> 
         </RelOp> 
         </TopSort> 
        </RelOp> 
        </Parallelism> 
       </RelOp> 
       </Top> 
      </RelOp> 
      </QueryPlan> 
     </StmtSimple> 
     </Statements> 
    </Batch> 
    </BatchSequence> 
</ShowPlanXML> 
+1

我不確定,但一個獨特的索引對性能沒有幫助我認爲你需要一個普通索引 – GuidoG

+0

我首先嚐試了普通索引,它是一樣的。 – ca9163d9

+0

A和B的數據類型是什麼? – GuidoG

回答

5

您的表格由B分區。

索引繼承此分區方案,除非您另行指定。例如用

create unique index ix_ on T (A, B) with (data_compression = page) on [primary] 

(在這種情況下,它變爲非對齊並防止一些操作例如元數據僅切換)

最低「A」值可能是在任何分區。

這並沒有得到很好的優化。你可以保持一致指數和使用該重寫based on the code here

SELECT TOP 20 A, B 
FROM sys.partitions AS P 
    CROSS APPLY (SELECT TOP 20 A, B 
       FROM dbo.T 
       WHERE $PARTITION.YourPartitionFunction(T.B) = P.partition_number 
       ORDER BY A,B 
       ) AS A 
WHERE P.object_id = OBJECT_ID('dbo.T') 
AND P.index_id = INDEXPROPERTY(OBJECT_ID('dbo.T'), 'ix_', 'IndexID') 
ORDER BY A,B 

它會從每個41個分區(沒有排序)的,則820行導致從得到最終只是排序得到的前20行前20名(而不是全部42萬名)。

+0

但索引ix_未分區,查詢使用索引? – ca9163d9

+2

@ dc7a9163d9 - 索引已分區。請參閱計劃中的PartitionsAccessed PartitionCount =「41」。 - [如果未指定partition_scheme_name或filegroup並且對錶進行分區,則將索引放置在與基礎表相同的分區方案中,使用相同的分區列。](https://msdn.microsoft.com/zh- cn /我們/庫/ ms188783.aspx) –

+0

謝謝,除了元數據只切換。,是否有任何其他缺陷創建額外的非對齊索引? – ca9163d9