salve,
sto cercando di capire se in effetti l'Optimizer e' cosi' intelligente da escludere dall'inner query il processamento degli argomenti NON inclusi nella SELECT list esterna... e cosi' in effeti sembra... utilizzando SQL Sentry Plan Explorer (la versione base e' FREE, https://www.sentryone.com/plan-explorer), si evince che parrebbe di si...
su una mia tabella di test ho eseguito
SELECT innerTB.pax, innerTB.pens
FROM (
SELECT SUM(a.ImportoPensione) pens, sum(a.PaxA + a.PaxR) pax
FROM dbo.AGE_CONTI a
) AS innerTB;
e
SELECT innerTB.pax
FROM (
SELECT SUM(a.ImportoPensione) pens, sum(a.PaxA + a.PaxR) pax
FROM dbo.AGE_CONTI a
) AS innerTB;
2 batch leggeri che comportano in effetti una "trivial optimization" per uno scan di 6000 righe...
il piano generato comporta un clustered index scan (97%), un compute scalar (0%), uno stream aggregate (3%), un successivo compute scalar (0%) ed il finale select(0%)
la precentuale indica il costo percentuale sul totale del batch.
al di la' ovviamente del medesimo costo in termini di righe man mano passati di step in step, si evince gia' da SSMS un minor costo di step in step in termini di bytes passati, qui mi e' venuto il dubbio... il pacchetto iniziale avrebbe dovuto essere del medesimo peso, nel mio caso 18 B per l'estimated row size del clustered index scan, mentre nel caso di omissione della colonna esterna [innerTB].[pens], l'estimated row size indica 9B, quindi in effetti sembra che l'aggregazione di SUM(a.ImportoPensione) pens non venga eseguita...
passando a SQL Sentry Plan Explorer, in effetti, la proiezione completa inclusiva di [pens] riporta un clustered index scan come segue:
<RelOp NodeId="3" PhysicalOp="Clustered Index Scan" LogicalOp="Clustered Index Scan" EstimateRows="6175" EstimateIO="0.119421" EstimateCPU="0.0069495" AvgRowSize="18" EstimatedTotalSubtreeCost="0.126371" TableCardinality="6175" Parallel="0" EstimateRebinds="0" EstimateRewinds="0" EstimatedExecutionMode="Row">
<OutputList>
<ColumnReference Database="[VbHotel]" Schema="[dbo]" Table="[AGE_CONTI]" Alias="[a]" Column="PaxA" />
<ColumnReference Database="[VbHotel]" Schema="[dbo]" Table="[AGE_CONTI]" Alias="[a]" Column="PaxR" />
<ColumnReference Database="[VbHotel]" Schema="[dbo]" Table="[AGE_CONTI]" Alias="[a]" Column="ImportoPensione" />
</OutputList>
<RunTimeInformation>
<RunTimeCountersPerThread Thread="0" ActualRows="6175" ActualElapsedms="0" ActualCPUms="0" ActualScans="1" ActualLogicalReads="160" ActualPhysicalReads="0" ActualReadAheads="0" ActualLobLogicalReads="0" ActualLobPhysicalReads="0" ActualLobReadAheads="0" ActualRowsRead="6175" ActualEndOfScans="1" ActualExecutions="1" />
</RunTimeInformation>
<IndexScan Ordered="0" ForcedIndex="0" ForceScan="0" NoExpandHint="0" Storage="RowStore">
<DefinedValues>
<DefinedValue>
<ColumnReference Database="[VbHotel]" Schema="[dbo]" Table="[AGE_CONTI]" Alias="[a]" Column="PaxA" />
</DefinedValue>
<DefinedValue>
<ColumnReference Database="[VbHotel]" Schema="[dbo]" Table="[AGE_CONTI]" Alias="[a]" Column="PaxR" />
</DefinedValue>
<DefinedValue>
<ColumnReference Database="[VbHotel]" Schema="[dbo]" Table="[AGE_CONTI]" Alias="[a]" Column="ImportoPensione" />
</DefinedValue>
</DefinedValues>
<Object Database="[VbHotel]" Schema="[dbo]" Table="[AGE_CONTI]" Index="[IX_age_contiArr]" Alias="[a]" IndexKind="Clustered" Storage="RowStore" />
</IndexScan>
</RelOp>
mentre la medesima operazione SENZA la proiezione finale di [pens] riporta:
<RelOp NodeId="3" PhysicalOp="Clustered Index Scan" LogicalOp="Clustered Index Scan" EstimateRows="6175" EstimateIO="0.119421" EstimateCPU="0.0069495" AvgRowSize="9" EstimatedTotalSubtreeCost="0.126371" TableCardinality="6175" Parallel="0" EstimateRebinds="0" EstimateRewinds="0" EstimatedExecutionMode="Row">
<OutputList>
<ColumnReference Database="[VbHotel]" Schema="[dbo]" Table="[AGE_CONTI]" Alias="[a]" Column="PaxA" />
<ColumnReference Database="[VbHotel]" Schema="[dbo]" Table="[AGE_CONTI]" Alias="[a]" Column="PaxR" />
</OutputList>
<RunTimeInformation>
<RunTimeCountersPerThread Thread="0" ActualRows="6175" ActualElapsedms="0" ActualCPUms="0" ActualScans="1" ActualLogicalReads="160" ActualPhysicalReads="0" ActualReadAheads="0" ActualLobLogicalReads="0" ActualLobPhysicalReads="0" ActualLobReadAheads="0" ActualRowsRead="6175" ActualEndOfScans="1" ActualExecutions="1" />
</RunTimeInformation>
<IndexScan Ordered="0" ForcedIndex="0" ForceScan="0" NoExpandHint="0" Storage="RowStore">
<DefinedValues>
<DefinedValue>
<ColumnReference Database="[VbHotel]" Schema="[dbo]" Table="[AGE_CONTI]" Alias="[a]" Column="PaxA" />
</DefinedValue>
<DefinedValue>
<ColumnReference Database="[VbHotel]" Schema="[dbo]" Table="[AGE_CONTI]" Alias="[a]" Column="PaxR" />
</DefinedValue>
</DefinedValues>
<Object Database="[VbHotel]" Schema="[dbo]" Table="[AGE_CONTI]" Index="[IX_age_contiArr]" Alias="[a]" IndexKind="Clustered" Storage="RowStore" />
</IndexScan>
</RelOp>
dove NON appare in effetti
<ColumnReference Database="[VbHotel]" Schema="[dbo]" Table="[AGE_CONTI]" Alias="[a]" Column="ImportoPensione" />
che quindi gia' a livello di sub query NON viene valutato, scartato dall'Optimzer in quanto NON referenziato nella outer SELECT list...
grazie, non me lo ricordavo... anche oggi ho imparato qualche cosa toccandola con mano :)
saluti