2013-08-27 7 views
5

Ho difficoltà a capire perché una query apparentemente semplice che esegue un join interno su 2 tabelle genera un conteggio stimato di 1, quando il valore effettivo è quasi 2 milioni. Non vedo alcun problema con gli indici mancanti e il 98% del costo della query avviene come ricerca per indice. Non vedo alcun I/O o flag rosso della CPU quando eseguono query, il che richiede circa 12 secondi. L'aggiunta di statistiche non sembra avere senso qui dato che la query si sta semplicemente unendo agli id, e entrambe le tabelle hanno indici raggruppati su quegli id ​​come chiavi primarie.Simple Inner Join su 2 tabelle risultanti in righe stimate errate e prestazioni lente

Questa query è una versione semplificata di una query più ampia che presenta gli stessi problemi, ma l'ho ridotta a questa query semplificata che presenta lo stesso problema. Presumo che la discrepanza tra le righe stimate e quelle effettive contribuisca almeno a prestazioni di query non ottimali. È interessante notare che la sostituzione di UN OUTER JOIN LEFT per INNER JOIN porta all'incirca alle stesse prestazioni, anche se le correzioni delle Righe Stimate sono corrette.

Query:

SELECT StationId, Readings.Power, Readings.TimeCovered 
FROM Readings 
INNER JOIN Stations ON Readings.StationId = Stations.Id 

effettivo piano XML:

<?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.1" Build="10.50.1600.1" xmlns="http://schemas.microsoft.com/sqlserver/2004/07/showplan"> 
    <BatchSequence> 
    <Batch> 
     <Statements> 
     <StmtSimple StatementCompId="1" StatementEstRows="1" StatementId="1" StatementOptmLevel="FULL" StatementOptmEarlyAbortReason="GoodEnoughPlanFound" StatementSubTreeCost="0.388499" StatementText="SELECT StationId,&#xD;&#xA;[Readings].[Power], [Readings].[TimeCovered]&#xD;&#xA;FROM [dbo].[Readings]&#xD;&#xA;INNER JOIN [dbo].[Stations] ON [Readings].[StationId] = [Stations].[Id]" StatementType="SELECT" QueryHash="0x540DF2384788314E" QueryPlanHash="0x7546B31B38AC8153"> 
      <StatementSetOptions ANSI_NULLS="true" ANSI_PADDING="true" ANSI_WARNINGS="true" ARITHABORT="false" CONCAT_NULL_YIELDS_NULL="true" NUMERIC_ROUNDABORT="false" QUOTED_IDENTIFIER="true" /> 
      <QueryPlan DegreeOfParallelism="1" CachedPlanSize="24" CompileTime="3" CompileCPU="3" CompileMemory="224"> 
      <RelOp AvgRowSize="17" EstimateCPU="0.00118294" EstimateIO="0" EstimateRebinds="0" EstimateRewinds="0" EstimateRows="1" LogicalOp="Inner Join" NodeId="0" Parallel="false" PhysicalOp="Nested Loops" EstimatedTotalSubtreeCost="0.388499"> 
       <OutputList> 
       <ColumnReference Database="[MyDB]" Schema="[dbo]" Table="[Readings]" Column="StationId" /> 
       <ColumnReference Database="[MyDB]" Schema="[dbo]" Table="[Readings]" Column="Power" /> 
       <ColumnReference Database="[MyDB]" Schema="[dbo]" Table="[Readings]" Column="TimeCovered" /> 
       </OutputList> 
       <RunTimeInformation> 
       <RunTimeCountersPerThread Thread="0" ActualRows="1898419" ActualEndOfScans="1" ActualExecutions="1" /> 
       </RunTimeInformation> 
       <NestedLoops Optimized="false"> 
       <OuterReferences> 
        <ColumnReference Database="[MyDB]" Schema="[dbo]" Table="[Stations]" Column="Id" /> 
       </OuterReferences> 
       <RelOp AvgRowSize="11" EstimateCPU="0.0004683" EstimateIO="0.00608796" EstimateRebinds="0" EstimateRewinds="0" EstimateRows="283" LogicalOp="Clustered Index Scan" NodeId="1" Parallel="false" PhysicalOp="Clustered Index Scan" EstimatedTotalSubtreeCost="0.00655626" TableCardinality="283"> 
        <OutputList> 
        <ColumnReference Database="[MyDB]" Schema="[dbo]" Table="[Stations]" Column="Id" /> 
        </OutputList> 
        <RunTimeInformation> 
        <RunTimeCountersPerThread Thread="0" ActualRows="283" ActualEndOfScans="1" ActualExecutions="1" /> 
        </RunTimeInformation> 
        <IndexScan Ordered="false" ForcedIndex="false" NoExpandHint="false"> 
        <DefinedValues> 
         <DefinedValue> 
         <ColumnReference Database="[MyDB]" Schema="[dbo]" Table="[Stations]" Column="Id" /> 
         </DefinedValue> 
        </DefinedValues> 
        <Object Database="[MyDB]" Schema="[dbo]" Table="[Stations]" Index="[PK_Stations]" IndexKind="Clustered" /> 
        </IndexScan> 
       </RelOp> 
       <RelOp AvgRowSize="17" EstimateCPU="0.0012571" EstimateIO="0.025" EstimateRebinds="0" EstimateRewinds="282" EstimateRows="1" LogicalOp="Index Seek" NodeId="2" Parallel="false" Partitioned="true" PhysicalOp="Index Seek" EstimatedTotalSubtreeCost="0.380759" TableCardinality="4246720"> 
        <OutputList> 
        <ColumnReference Database="[MyDB]" Schema="[dbo]" Table="[Readings]" Column="StationId" /> 
        <ColumnReference Database="[MyDB]" Schema="[dbo]" Table="[Readings]" Column="Power" /> 
        <ColumnReference Database="[MyDB]" Schema="[dbo]" Table="[Readings]" Column="TimeCovered" /> 
        </OutputList> 
        <RunTimeInformation> 
        <RunTimeCountersPerThread Thread="0" ActualRows="1898419" ActualEndOfScans="283" ActualExecutions="283" /> 
        </RunTimeInformation> 
        <RunTimePartitionSummary> 
        <PartitionsAccessed PartitionCount="8"> 
         <PartitionRange Start="1" End="8" /> 
        </PartitionsAccessed> 
        </RunTimePartitionSummary> 
        <IndexScan Ordered="true" ScanDirection="FORWARD" ForcedIndex="false" ForceSeek="false" NoExpandHint="false"> 
        <DefinedValues> 
         <DefinedValue> 
         <ColumnReference Database="[MyDB]" Schema="[dbo]" Table="[Readings]" Column="StationId" /> 
         </DefinedValue> 
         <DefinedValue> 
         <ColumnReference Database="[MyDB]" Schema="[dbo]" Table="[Readings]" Column="Power" /> 
         </DefinedValue> 
         <DefinedValue> 
         <ColumnReference Database="[MyDB]" Schema="[dbo]" Table="[Readings]" Column="TimeCovered" /> 
         </DefinedValue> 
        </DefinedValues> 
        <Object Database="[MyDB]" Schema="[dbo]" Table="[Readings]" Index="[IX_Readings_StationId_SecondsSinceEpoch]" IndexKind="NonClustered" /> 
        <SeekPredicates> 
         <SeekPredicateNew> 
         <SeekKeys> 
          <StartRange ScanType="GE"> 
          <RangeColumns> 
           <ColumnReference Column="PtnId1000" /> 
          </RangeColumns> 
          <RangeExpressions> 
           <ScalarOperator ScalarString="(1)"> 
           <Const ConstValue="(1)" /> 
           </ScalarOperator> 
          </RangeExpressions> 
          </StartRange> 
          <EndRange ScanType="LE"> 
          <RangeColumns> 
           <ColumnReference Column="PtnId1000" /> 
          </RangeColumns> 
          <RangeExpressions> 
           <ScalarOperator ScalarString="(8)"> 
           <Const ConstValue="(8)" /> 
           </ScalarOperator> 
          </RangeExpressions> 
          </EndRange> 
         </SeekKeys> 
         <SeekKeys> 
          <Prefix ScanType="EQ"> 
          <RangeColumns> 
           <ColumnReference Database="[MyDB]" Schema="[dbo]" Table="[Readings]" Column="StationId" /> 
          </RangeColumns> 
          <RangeExpressions> 
           <ScalarOperator ScalarString="[MyDB].[dbo].[Stations].[Id]"> 
           <Identifier> 
            <ColumnReference Database="[MyDB]" Schema="[dbo]" Table="[Stations]" Column="Id" /> 
           </Identifier> 
           </ScalarOperator> 
          </RangeExpressions> 
          </Prefix> 
         </SeekKeys> 
         </SeekPredicateNew> 
        </SeekPredicates> 
        </IndexScan> 
       </RelOp> 
       </NestedLoops> 
      </RelOp> 
      </QueryPlan> 
     </StmtSimple> 
     </Statements> 
    </Batch> 
    </BatchSequence> 
</ShowPlanXML> 
+1

Le statistiche non aggiornate potrebbero avere qualcosa a che fare con questo. Prova a eseguire un 'exec sp_updatestats' e verifica se il piano cambia. – Magnus

+0

Magnus, questo sembra aver aiutato! La query riporta ora circa 4k, che moltiplicato per 283 è pari al numero totale di righe. Fammi controllare se la query originale è stata risolta da questo. – DavidN

+0

Magnus, ha funzionato meravigliosamente. Grazie ancora per tutto il tuo aiuto. – DavidN

risposta

2

statistiche non aggiornato potrebbe avere qualcosa a che fare con esso. Prova a eseguire un exec sp_updatestats e verifica se il piano cambia. Assicurarsi inoltre di avere un lavoro di manutenzione in esecuzione sul server SQL che aggiorna periodicamente le statistiche.