Obwohl ich mit vielen verschiedenen DBMS gearbeitet habe, werde ich Ihnen nur das Ergebnis der Beweisführung auf SQL Server zeigen. Betrachten Sie diese Abfrage, die sogar einen CAST im Ausdruck enthält. Beim Betrachten des Abfrageplans wird der Ausdruck sum(cast(number as bigint))
nur einmal verwendet, was als DEFINE:([Expr1005]=SUM([Expr1006]))
definiert ist.
set showplan_text on
select type, sum(cast(number as bigint))
from master..spt_values
group by type
having sum(cast(number as bigint)) > 100000
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|--Filter(WHERE:([Expr1005]>(100000)))
|--Hash Match(Aggregate, HASH:([Expr1004]), RESIDUAL:([Expr1004] = [Expr1004]) DEFINE:([Expr1005]=SUM([Expr1006])))
|--Compute Scalar(DEFINE:([Expr1004]=CONVERT(nchar(3),[mssqlsystemresource].[sys].[spt_values].[type],0), [Expr1006]=CONVERT(bigint,[mssqlsystemresource].[sys].[spt_values].[number],0)))
|--Index Scan(OBJECT:([mssqlsystemresource].[sys].[spt_values].[ix2_spt_values_nu_nc]))
Es kann nicht sehr offensichtlich oben sein, da es nicht das SELECT-Ergebnis nicht zeigt, so habe ich ein *10
auf die Abfrage unten hinzugefügt. Beachten Sie, dass jetzt ein zusätzlicher Schritt DEFINE:([Expr1006]=[Expr1005]*(10))
(Schritte von unten nach oben) enthalten ist, der zeigt, dass der neue Ausdruck eine zusätzliche Berechnung erfordert. Aber auch dies ist optimiert, da es nicht den gesamten Ausdruck neu berechnet - lediglich Expr1005 wird genommen und mit 10 multipliziert!
set showplan_text on
select type, sum(cast(number as bigint))*10
from master..spt_values
group by type
having sum(cast(number as bigint)) > 100000
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|--Compute Scalar(DEFINE:([Expr1006]=[Expr1005]*(10)))
|--Filter(WHERE:([Expr1005]>(100000)))
|--Hash Match(Aggregate, HASH:([Expr1004]), RESIDUAL:([Expr1004] = [Expr1004]) DEFINE:([Expr1005]=SUM([Expr1007])))
|--Compute Scalar(DEFINE:([Expr1004]=CONVERT(nchar(3),[mssqlsystemresource].[sys].[spt_values].[type],0), [Expr1007]=CONVERT(bigint,[mssqlsystemresource].[sys].[spt_values].[number],0)))
|--Index Scan(OBJECT:([mssqlsystemresource].[sys].[spt_values].[ix2_spt_values_nu_nc]))
Dies ist sehr wahrscheinlich, wie alle anderen DBMS so gut funktionieren, zumindest die wichtigsten auf Berücksichtigung heißt PostgreSQL, Sybase, Oracle, DB2, Firebird, MySQL.