2012-01-16 4 views
3

У меня есть две таблицы, в которых хранятся суммы и корректировки для типов LineItemTypes определенного периода ReportingPeriod. Я ищу наиболее эффективный способ запроса суммы и корректировки для каждой комбинации ReportingPeriod/LineItemType, которая существует в двух таблицах.Как наиболее эффективно объединить две таблицы?

Схемы присутствуют ниже:

@ReportingPeriodComposition (1030 строк - таблица с переменной)

Src int, 
GroupReportingPeriodId int, 
ReportingPeriodId int, 
ClientId int, 
PeriodDate date, 
... 
PRIMARY KEY CLUSTERED (Src, ReportingPeriodId) 

Сумма (~ 30000000 строк)

ReportingPeriodId int, 
LineItemTypeId smallint, 
Amount decimal, 
PRIMARY KEY CLUSTERED (ReportingPeriodId, LineItemTypeId) 

Регулировка (~ 180 000 строк)

ReportingPeriodId int, 
LineItemTypeId smallint, 
Amount decimal, 
Comment nvarchar(2500), 
... 
AdjustmentId int, 
PRIMARY KEY NONCLUSTERED (AdjustmentId), 
UNIQUE KEY CLUSTERED (ReportingPeriodId, LineItemTypeId) 

Я хотел бы, чтобы выбрать Количества и регулировки по уникальной ReportingPeriodId/LineItemTypeId получая следующий результирующий набор:

| ReportingPeriodId | LineItemTypeId | Amount | Adjustment | 

В настоящее время я использую следующий запрос, но мне любопытно посмотреть, если кто-нибудь есть мысли о том, как это можно сделать более эффективно. Все предложения приветствуются!

SELECT 
    rpc.ReportingPeriodId, 
    COALESCE(a.LineItemTypeId, adj.LineItemTypeId) LineItemTypeId, 
    a.Amount, 
    adj.Amount Adjustment 
FROM @ReportingPeriodComposition rpc 
LEFT JOIN Watchlist.risk.Amount a 
    ON rpc.ReportingPeriodId = a.ReportingPeriodId 
LEFT JOIN Watchlist.risk.Adjustment adj 
    ON rpc.ReportingPeriodId = adj.ReportingPeriodId 
    AND (a.ReportingPeriodId IS NULL OR a.LineItemTypeId = adj.LineItemTypeId) 
WHERE 
    Src = @Src 
    AND (a.LineItemTypeId IS NOT NULL OR adj.LineItemTypeId IS NOT NULL) 

Обратите внимание, что переменная @Src необходимо определить, какие значения источника мы должны вытащить из переменной @ReportingPeriodComposition таблицы. Результаты запроса в ~ 138000 строк:

  • 1 строка имеет как количество и корректировку, хотя это число может изменяться в зависимости от ReportingPeriodComposition
  • 0 строки имеет только корректировку, хотя это условие не гарантируется

плана выполнения 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.0.4064.0" xmlns="http://schemas.microsoft.com/sqlserver/2004/07/showplan"> 
    <BatchSequence> 
    <Batch> 
     <Statements> 
     <StmtSimple StatementCompId="9" StatementEstRows="104.769" StatementId="5" StatementOptmLevel="FULL" StatementOptmEarlyAbortReason="GoodEnoughPlanFound" StatementSubTreeCost="0.343989" StatementText="SELECT&#xD;&#xA; rpc.ReportingPeriodId,&#xD;&#xA; COALESCE(a.LineItemTypeId, adj.LineItemTypeId) LineItemTypeId,&#xD;&#xA; a.Amount,&#xD;&#xA; adj.Amount Adjustment&#xD;&#xA;FROM @ReportingPeriodComposition rpc&#xD;&#xA;LEFT JOIN Rating.risk.Amount a&#xD;&#xA; ON rpc.ReportingPeriodId = a.ReportingPeriodId&#xD;&#xA;LEFT JOIN Rating.risk.Adjustment adj&#xD;&#xA; ON rpc.ReportingPeriodId = adj.ReportingPeriodId&#xD;&#xA; AND (a.ReportingPeriodId IS NULL OR a.LineItemTypeId = adj.LineItemTypeId)&#xD;&#xA;WHERE&#xD;&#xA; Src = @Src&#xD;&#xA; AND (a.LineItemTypeId IS NOT NULL OR adj.LineItemTypeId IS NOT NULL)" StatementType="SELECT" QueryHash="0x425781A4C1D20919" QueryPlanHash="0xF3E9DD0ADAD04044"> 
      <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="1" CachedPlanSize="24" CompileTime="5" CompileCPU="5" CompileMemory="424"> 
      <RelOp AvgRowSize="31" EstimateCPU="1.04769E-05" EstimateIO="0" EstimateRebinds="0" EstimateRewinds="0" EstimateRows="104.769" LogicalOp="Compute Scalar" NodeId="0" Parallel="false" PhysicalOp="Compute Scalar" EstimatedTotalSubtreeCost="0.343989"> 
       <OutputList> 
       <ColumnReference Table="@ReportingPeriodComposition" Alias="[rpc]" Column="ReportingPeriodId" /> 
       <ColumnReference Database="[Rating]" Schema="[risk]" Table="[Amount]" Alias="[a]" Column="Amount" /> 
       <ColumnReference Database="[Rating]" Schema="[risk]" Table="[Adjustment]" Alias="[adj]" Column="Amount" /> 
       <ColumnReference Column="Expr1006" /> 
       </OutputList> 
       <ComputeScalar> 
       <DefinedValues> 
        <DefinedValue> 
        <ColumnReference Column="Expr1006" /> 
        <ScalarOperator ScalarString="CASE WHEN [Rating].[risk].[Amount].[LineItemTypeId] as [a].[LineItemTypeId] IS NOT NULL THEN [Rating].[risk].[Amount].[LineItemTypeId] as [a].[LineItemTypeId] ELSE [Rating].[risk].[Adjustment].[LineItemTypeId] as [adj].[LineItemTypeId] END"> 
         <IF> 
         <Condition> 
          <ScalarOperator> 
          <Compare CompareOp="IS NOT"> 
           <ScalarOperator> 
           <Identifier> 
            <ColumnReference Database="[Rating]" Schema="[risk]" Table="[Amount]" Alias="[a]" Column="LineItemTypeId" /> 
           </Identifier> 
           </ScalarOperator> 
           <ScalarOperator> 
           <Const ConstValue="NULL" /> 
           </ScalarOperator> 
          </Compare> 
          </ScalarOperator> 
         </Condition> 
         <Then> 
          <ScalarOperator> 
          <Identifier> 
           <ColumnReference Database="[Rating]" Schema="[risk]" Table="[Amount]" Alias="[a]" Column="LineItemTypeId" /> 
          </Identifier> 
          </ScalarOperator> 
         </Then> 
         <Else> 
          <ScalarOperator> 
          <Identifier> 
           <ColumnReference Database="[Rating]" Schema="[risk]" Table="[Adjustment]" Alias="[adj]" Column="LineItemTypeId" /> 
          </Identifier> 
          </ScalarOperator> 
         </Else> 
         </IF> 
        </ScalarOperator> 
        </DefinedValue> 
       </DefinedValues> 
       <RelOp AvgRowSize="33" EstimateCPU="9.21971E-05" EstimateIO="0" EstimateRebinds="0" EstimateRewinds="0" EstimateRows="104.769" LogicalOp="Filter" NodeId="1" Parallel="false" PhysicalOp="Filter" EstimatedTotalSubtreeCost="0.343979"> 
        <OutputList> 
        <ColumnReference Table="@ReportingPeriodComposition" Alias="[rpc]" Column="ReportingPeriodId" /> 
        <ColumnReference Database="[Rating]" Schema="[risk]" Table="[Amount]" Alias="[a]" Column="LineItemTypeId" /> 
        <ColumnReference Database="[Rating]" Schema="[risk]" Table="[Amount]" Alias="[a]" Column="Amount" /> 
        <ColumnReference Database="[Rating]" Schema="[risk]" Table="[Adjustment]" Alias="[adj]" Column="LineItemTypeId" /> 
        <ColumnReference Database="[Rating]" Schema="[risk]" Table="[Adjustment]" Alias="[adj]" Column="Amount" /> 
        </OutputList> 
        <RunTimeInformation> 
        <RunTimeCountersPerThread Thread="0" ActualRows="137631" ActualEndOfScans="1" ActualExecutions="1" /> 
        </RunTimeInformation> 
        <Filter StartupExpression="false"> 
        <RelOp AvgRowSize="33" EstimateCPU="0.000437936" EstimateIO="0" EstimateRebinds="0" EstimateRewinds="0" EstimateRows="104.769" LogicalOp="Left Outer Join" NodeId="2" Parallel="false" PhysicalOp="Nested Loops" EstimatedTotalSubtreeCost="0.343886"> 
         <OutputList> 
         <ColumnReference Table="@ReportingPeriodComposition" Alias="[rpc]" Column="ReportingPeriodId" /> 
         <ColumnReference Database="[Rating]" Schema="[risk]" Table="[Amount]" Alias="[a]" Column="LineItemTypeId" /> 
         <ColumnReference Database="[Rating]" Schema="[risk]" Table="[Amount]" Alias="[a]" Column="Amount" /> 
         <ColumnReference Database="[Rating]" Schema="[risk]" Table="[Adjustment]" Alias="[adj]" Column="LineItemTypeId" /> 
         <ColumnReference Database="[Rating]" Schema="[risk]" Table="[Adjustment]" Alias="[adj]" Column="Amount" /> 
         </OutputList> 
         <RunTimeInformation> 
         <RunTimeCountersPerThread Thread="0" ActualRows="137647" ActualEndOfScans="1" ActualExecutions="1" /> 
         </RunTimeInformation> 
         <NestedLoops Optimized="false" WithUnorderedPrefetch="true"> 
         <OuterReferences> 
          <ColumnReference Table="@ReportingPeriodComposition" Alias="[rpc]" Column="ReportingPeriodId" /> 
          <ColumnReference Database="[Rating]" Schema="[risk]" Table="[Amount]" Alias="[a]" Column="ReportingPeriodId" /> 
          <ColumnReference Database="[Rating]" Schema="[risk]" Table="[Amount]" Alias="[a]" Column="LineItemTypeId" /> 
          <ColumnReference Column="Expr1009" /> 
         </OuterReferences> 
         <RelOp AvgRowSize="26" EstimateCPU="0.000437936" EstimateIO="0" EstimateRebinds="0" EstimateRewinds="0" EstimateRows="104.769" LogicalOp="Left Outer Join" NodeId="4" Parallel="false" PhysicalOp="Nested Loops" EstimatedTotalSubtreeCost="0.00711828"> 
          <OutputList> 
          <ColumnReference Table="@ReportingPeriodComposition" Alias="[rpc]" Column="ReportingPeriodId" /> 
          <ColumnReference Database="[Rating]" Schema="[risk]" Table="[Amount]" Alias="[a]" Column="ReportingPeriodId" /> 
          <ColumnReference Database="[Rating]" Schema="[risk]" Table="[Amount]" Alias="[a]" Column="LineItemTypeId" /> 
          <ColumnReference Database="[Rating]" Schema="[risk]" Table="[Amount]" Alias="[a]" Column="Amount" /> 
          </OutputList> 
          <RunTimeInformation> 
          <RunTimeCountersPerThread Thread="0" ActualRows="137647" ActualEndOfScans="1" ActualExecutions="1" /> 
          </RunTimeInformation> 
          <NestedLoops Optimized="false"> 
          <OuterReferences> 
           <ColumnReference Table="@ReportingPeriodComposition" Alias="[rpc]" Column="ReportingPeriodId" /> 
          </OuterReferences> 
          <RelOp AvgRowSize="11" EstimateCPU="0.0001581" EstimateIO="0.003125" EstimateRebinds="0" EstimateRewinds="0" EstimateRows="1" LogicalOp="Clustered Index Seek" NodeId="5" Parallel="false" PhysicalOp="Clustered Index Seek" EstimatedTotalSubtreeCost="0.0032831" TableCardinality="0"> 
           <OutputList> 
           <ColumnReference Table="@ReportingPeriodComposition" Alias="[rpc]" Column="ReportingPeriodId" /> 
           </OutputList> 
           <RunTimeInformation> 
           <RunTimeCountersPerThread Thread="0" ActualRows="1030" ActualEndOfScans="1" ActualExecutions="1" /> 
           </RunTimeInformation> 
           <IndexScan Ordered="true" ScanDirection="FORWARD" ForcedIndex="false" ForceSeek="false" NoExpandHint="false"> 
           <DefinedValues> 
            <DefinedValue> 
            <ColumnReference Table="@ReportingPeriodComposition" Alias="[rpc]" Column="ReportingPeriodId" /> 
            </DefinedValue> 
           </DefinedValues> 
           <Object Table="[@ReportingPeriodComposition]" Index="[PK__#6FDF7DF__F9ABEE3F71C7C670]" Alias="[rpc]" /> 
           <SeekPredicates> 
            <SeekPredicateNew> 
            <SeekKeys> 
             <Prefix ScanType="EQ"> 
             <RangeColumns> 
              <ColumnReference Table="@ReportingPeriodComposition" Alias="[rpc]" Column="Src" /> 
             </RangeColumns> 
             <RangeExpressions> 
              <ScalarOperator ScalarString="[@Src]"> 
              <Identifier> 
               <ColumnReference Column="@Src" /> 
              </Identifier> 
              </ScalarOperator> 
             </RangeExpressions> 
             </Prefix> 
            </SeekKeys> 
            </SeekPredicateNew> 
           </SeekPredicates> 
           </IndexScan> 
          </RelOp> 
          <RelOp AvgRowSize="22" EstimateCPU="0.000272246" EstimateIO="0.003125" EstimateRebinds="0" EstimateRewinds="0" EstimateRows="104.769" LogicalOp="Clustered Index Seek" NodeId="6" Parallel="false" PhysicalOp="Clustered Index Seek" EstimatedTotalSubtreeCost="0.00339725" TableCardinality="29974300"> 
           <OutputList> 
           <ColumnReference Database="[Rating]" Schema="[risk]" Table="[Amount]" Alias="[a]" Column="ReportingPeriodId" /> 
           <ColumnReference Database="[Rating]" Schema="[risk]" Table="[Amount]" Alias="[a]" Column="LineItemTypeId" /> 
           <ColumnReference Database="[Rating]" Schema="[risk]" Table="[Amount]" Alias="[a]" Column="Amount" /> 
           </OutputList> 
           <RunTimeInformation> 
           <RunTimeCountersPerThread Thread="0" ActualRows="137631" ActualEndOfScans="1030" ActualExecutions="1030" /> 
           </RunTimeInformation> 
           <IndexScan Ordered="true" ScanDirection="FORWARD" ForcedIndex="false" ForceSeek="false" NoExpandHint="false"> 
           <DefinedValues> 
            <DefinedValue> 
            <ColumnReference Database="[Rating]" Schema="[risk]" Table="[Amount]" Alias="[a]" Column="ReportingPeriodId" /> 
            </DefinedValue> 
            <DefinedValue> 
            <ColumnReference Database="[Rating]" Schema="[risk]" Table="[Amount]" Alias="[a]" Column="LineItemTypeId" /> 
            </DefinedValue> 
            <DefinedValue> 
            <ColumnReference Database="[Rating]" Schema="[risk]" Table="[Amount]" Alias="[a]" Column="Amount" /> 
            </DefinedValue> 
           </DefinedValues> 
           <Object Database="[Rating]" Schema="[risk]" Table="[Amount]" Index="[PK_Amount]" Alias="[a]" IndexKind="Clustered" /> 
           <SeekPredicates> 
            <SeekPredicateNew> 
            <SeekKeys> 
             <Prefix ScanType="EQ"> 
             <RangeColumns> 
              <ColumnReference Database="[Rating]" Schema="[risk]" Table="[Amount]" Alias="[a]" Column="ReportingPeriodId" /> 
             </RangeColumns> 
             <RangeExpressions> 
              <ScalarOperator ScalarString="@ReportingPeriodComposition.[ReportingPeriodId] as [rpc].[ReportingPeriodId]"> 
              <Identifier> 
               <ColumnReference Table="@ReportingPeriodComposition" Alias="[rpc]" Column="ReportingPeriodId" /> 
              </Identifier> 
              </ScalarOperator> 
             </RangeExpressions> 
             </Prefix> 
            </SeekKeys> 
            </SeekPredicateNew> 
           </SeekPredicates> 
           </IndexScan> 
          </RelOp> 
          </NestedLoops> 
         </RelOp> 
         <RelOp AvgRowSize="18" EstimateCPU="0.000165111" EstimateIO="0.003125" EstimateRebinds="103.769" EstimateRewinds="0" EstimateRows="1" LogicalOp="Clustered Index Seek" NodeId="7" Parallel="false" PhysicalOp="Clustered Index Seek" EstimatedTotalSubtreeCost="0.33565" TableCardinality="178911"> 
          <OutputList> 
          <ColumnReference Database="[Rating]" Schema="[risk]" Table="[Adjustment]" Alias="[adj]" Column="LineItemTypeId" /> 
          <ColumnReference Database="[Rating]" Schema="[risk]" Table="[Adjustment]" Alias="[adj]" Column="Amount" /> 
          </OutputList> 
          <RunTimeInformation> 
          <RunTimeCountersPerThread Thread="0" ActualRows="1" ActualEndOfScans="137647" ActualExecutions="137647" /> 
          </RunTimeInformation> 
          <IndexScan Ordered="true" ScanDirection="FORWARD" ForcedIndex="false" ForceSeek="false" NoExpandHint="false"> 
          <DefinedValues> 
           <DefinedValue> 
           <ColumnReference Database="[Rating]" Schema="[risk]" Table="[Adjustment]" Alias="[adj]" Column="LineItemTypeId" /> 
           </DefinedValue> 
           <DefinedValue> 
           <ColumnReference Database="[Rating]" Schema="[risk]" Table="[Adjustment]" Alias="[adj]" Column="Amount" /> 
           </DefinedValue> 
          </DefinedValues> 
          <Object Database="[Rating]" Schema="[risk]" Table="[Adjustment]" Index="[IX_Adjustment_ReportingPeriodId_LineItemTypeId]" Alias="[adj]" IndexKind="Clustered" /> 
          <SeekPredicates> 
           <SeekPredicateNew> 
           <SeekKeys> 
            <Prefix ScanType="EQ"> 
            <RangeColumns> 
             <ColumnReference Database="[Rating]" Schema="[risk]" Table="[Adjustment]" Alias="[adj]" Column="ReportingPeriodId" /> 
            </RangeColumns> 
            <RangeExpressions> 
             <ScalarOperator ScalarString="@ReportingPeriodComposition.[ReportingPeriodId] as [rpc].[ReportingPeriodId]"> 
             <Identifier> 
              <ColumnReference Table="@ReportingPeriodComposition" Alias="[rpc]" Column="ReportingPeriodId" /> 
             </Identifier> 
             </ScalarOperator> 
            </RangeExpressions> 
            </Prefix> 
           </SeekKeys> 
           </SeekPredicateNew> 
          </SeekPredicates> 
          <Predicate> 
           <ScalarOperator ScalarString="[Rating].[risk].[Amount].[ReportingPeriodId] as [a].[ReportingPeriodId] IS NULL OR [Rating].[risk].[Amount].[LineItemTypeId] as [a].[LineItemTypeId]=[Rating].[risk].[Adjustment].[LineItemTypeId] as [adj].[LineItemTypeId]"> 
           <Logical Operation="OR"> 
            <ScalarOperator> 
            <Compare CompareOp="IS"> 
             <ScalarOperator> 
             <Identifier> 
              <ColumnReference Database="[Rating]" Schema="[risk]" Table="[Amount]" Alias="[a]" Column="ReportingPeriodId" /> 
             </Identifier> 
             </ScalarOperator> 
             <ScalarOperator> 
             <Const ConstValue="NULL" /> 
             </ScalarOperator> 
            </Compare> 
            </ScalarOperator> 
            <ScalarOperator> 
            <Compare CompareOp="EQ"> 
             <ScalarOperator> 
             <Identifier> 
              <ColumnReference Database="[Rating]" Schema="[risk]" Table="[Amount]" Alias="[a]" Column="LineItemTypeId" /> 
             </Identifier> 
             </ScalarOperator> 
             <ScalarOperator> 
             <Identifier> 
              <ColumnReference Database="[Rating]" Schema="[risk]" Table="[Adjustment]" Alias="[adj]" Column="LineItemTypeId" /> 
             </Identifier> 
             </ScalarOperator> 
            </Compare> 
            </ScalarOperator> 
           </Logical> 
           </ScalarOperator> 
          </Predicate> 
          </IndexScan> 
         </RelOp> 
         </NestedLoops> 
        </RelOp> 
        <Predicate> 
         <ScalarOperator ScalarString="[Rating].[risk].[Amount].[LineItemTypeId] as [a].[LineItemTypeId] IS NOT NULL OR [Rating].[risk].[Adjustment].[LineItemTypeId] as [adj].[LineItemTypeId] IS NOT NULL"> 
         <Logical Operation="OR"> 
          <ScalarOperator> 
          <Compare CompareOp="IS NOT"> 
           <ScalarOperator> 
           <Identifier> 
            <ColumnReference Database="[Rating]" Schema="[risk]" Table="[Amount]" Alias="[a]" Column="LineItemTypeId" /> 
           </Identifier> 
           </ScalarOperator> 
           <ScalarOperator> 
           <Const ConstValue="NULL" /> 
           </ScalarOperator> 
          </Compare> 
          </ScalarOperator> 
          <ScalarOperator> 
          <Compare CompareOp="IS NOT"> 
           <ScalarOperator> 
           <Identifier> 
            <ColumnReference Database="[Rating]" Schema="[risk]" Table="[Adjustment]" Alias="[adj]" Column="LineItemTypeId" /> 
           </Identifier> 
           </ScalarOperator> 
           <ScalarOperator> 
           <Const ConstValue="NULL" /> 
           </ScalarOperator> 
          </Compare> 
          </ScalarOperator> 
         </Logical> 
         </ScalarOperator> 
        </Predicate> 
        </Filter> 
       </RelOp> 
       </ComputeScalar> 
      </RelOp> 
      <ParameterList> 
       <ColumnReference Column="@Src" ParameterRuntimeValue="(2)" /> 
      </ParameterList> 
      </QueryPlan> 
     </StmtSimple> 
     </Statements> 
    </Batch> 
    </BatchSequence> 
</ShowPlanXML> 
+1

Любая возможность показать план запроса, который он производит, - из приведенного описания и схемы ничего не получилось бы «очевидно» неправильно – Andrew

+0

Я могу это сделать. Как бы вы хотели, чтобы я это показал? –

+0

XML или Graphic, либо будет работать – Andrew

ответ

2

Нет ничего особенного в плане запроса, который вы опубликовали, я вижу - я подозреваю, что SQL делает правильный выбор. Единственное, что я мог заметить, немного уродливое, - это то, что оценки плана запроса и фактическое количество возвращенных строк довольно далеко друг от друга - что свидетельствует о том, что статистика не совсем обновлена ​​- вы можете принудительно обновить статистику и посмотреть, продолжает ли она использовать тот же план запроса.

Если у вас возникла проблема с непоследовательной производительностью, в блоке dev очистите кэш плана запроса и сформируйте план запроса для значения @SRC, который будет производить очень мало строк, затем очистите кэш плана и сформируйте план запроса для @SRC значение, которое будет выдавать очень большое количество строк для возврата. Если планы запросов одинаковы, вы в порядке, если они разные, вам может понадобиться использовать подсказку OPTIMIZE FOR. Это иногда случается при параметризованных запросах, где первый запуск их определяет план, который находится в кеше, - и до тех пор, пока этот план не возрастет, последующие прогоны запроса используют один и тот же план.

Теперь вам нужно предоставить более подробную информацию о том, какую конкретную проблему вы столкнулись/хотите решить, просмотрев ее?

1

Как насчет использования JOIN HINT?

Из MSDN:

LOOP | HASH | MERGE Указывает, что соединение в запросе должно использовать цикл , хеширование или слияние. Использование LOOP | HASH | MERGE JOIN обеспечивает привязку к между двумя таблицами. LOOP не может быть указан вместе с ПРАВОЙ или ПОЛНОЙ как тип соединения.

REMOTE Указывает, что операция соединения выполняется на сайте правой таблицы. Это полезно, когда левая таблица является локальной таблицей , а правая таблица - удаленной. REMOTE следует использовать только тогда, когда . В левой таблице меньше строк, чем в правой таблице.

Если правая таблица является локальной, объединение выполняется локально.Если обе таблицы удалены, но из разных источников данных, REMOTE вызывает соединение на сайте правой таблицы. Если обе таблицы - это удаленные таблицы из одного и того же источника данных, REMOTE не требуется.

REMOTE не может использоваться, когда одно из значений, сравниваемых в предикате соединения , отливается в другое сопоставление, используя предложение COLLATE .

REMOTE может использоваться только для операций INNER JOIN.

В вашем случае вы можете использовать соединение LOOP, так как вы имеете дело с LEFT join. Другое дело, что ваш запрос выглядит хорошо, у вас есть индексы на столбцах, на которые вы фильтруете?

В вашей таблице количества много строк, но я видел базы данных с гораздо большим количеством. С каким оборудованием вы работаете?

Для примера использования LOOP JOIN и показанной конкретной оптимизации см. Это article. Но все зависит от типа запроса при использовании подсказки соединения. Это может быть неприменимо и должно быть последним вариантом в вашем случае.

+0

Оптимизатор запросов выбирает выполнение вложенных циклов для левых внешних соединений. 98% случаев - это поиск кластеризованного индекса на IX_Adjustment_ReportingPeriodId_LineItemTypeId. 1 Фактическое количество строк, 137647 # Исполнений, 104.769 Оценочное количество казней –

0

Я бы постарался заменить @table_variable на таблицу #temp, чтобы у SQL Server была более точная статистика.

В настоящее время предполагается, что переменная таблицы вернет 1 строку и выберет план вложенных циклов. Вы можете получить другое, если оно может учитывать фактическую мощность стола.

Смежные вопросы