儘管我已經使用了許多不同的DBMS,但我只會向您顯示在SQL Server上證明這一點的結果。考慮這個查詢,它甚至在表達式中包含一個CAST。查看查詢計劃,表達式sum(cast(number as bigint))
僅取一次,其定義爲DEFINE:([Expr1005]=SUM([Expr1006]))
。
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]))
它可能不是很明顯上面,因爲它不顯示選擇的結果,所以我添加了一個*10
下面的查詢。注意它現在包含一個額外的步驟DEFINE:([Expr1006]=[Expr1005]*(10))
(步驟從下到上運行),這表明新表達式要求它執行額外的計算。然而,即使這樣做是最優化的,因爲它不會重新計算整個表達式 - 僅僅是將Expr1005乘以10!
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]))
這很可能是所有其他DBMS是如何工作的,以及,至少考慮到主要的PostgreSQL的即時,Sybase,甲骨文,DB2,火鳥,MySQL的。