常量折叠是否有两个级别,一个在转换树中,一个在简化阶段?
如果我运行以下查询
SELECT
P.[ProductID]
FROM
Production.Product AS P
WHERE
P.[ProductID] = 1 + 2 * 3
OPTION (RECOMPILE, QUERYTRACEON 8605, QUERYTRACEON 8606, QUERYTRACEON 8607, QUERYTRACEON 3604);
在转换树中,我发现一个常量,因此我将其称为基本常量折叠?
就像Paul Holmes在这个例子中所说的那样,但是如果我运行Paul White的这个查询
use AdventureWorks2016
begin tran
SELECT
P.[Name]
FROM Production.Product AS P
WHERE
P.[Name] LIKE
SUBSTRING(LEFT(CHAR(ASCII(CHAR(68))), 1) + '%', 1, 2)
OPTION (RECOMPILE, QUERYTRACEON 8605, QUERYTRACEON 8606, QUERYTRACEON 8607, QUERYTRACEON 3604);
commit tran
和
begin tran
SELECT
P.[Name]
FROM Production.Product AS P
WHERE
P.[Name] LIKE
'd%'
OPTION (RECOMPILE, QUERYTRACEON 8605, QUERYTRACEON 8606, QUERYTRACEON 8607, QUERYTRACEON 3604);
commit tran
就转换树而言,我没有发现两者之间有太大区别,所以常量折叠发生在这里,并且它们的简化树具有相同的运算符?
常量折叠有不同的阶段吗?它们在哪里?我在这里做错了什么,所以我在简化阶段没有看到它?
常数折叠可以在优化的不同阶段发生多次。
它在代数化过程中早期对标量运算符进行了全面执行。在当前版本的 SQL Server 中,在此阶段之前无法看到树很好地打印出来。
问题中的两个例子都展示了常量折叠的应用结果。其中一个看起来比另一个简单,纯粹是因为它的结果是一个整数而不是一个结构。
我的例子是不断折叠成一个
LikeRangeInfo
结构:您可以使用
CHAR
或NCHAR
来解码数字(结果显示为注释)。每当优化器活动出现新的折叠机会时,常量折叠也会在特定表达式上再次执行。
一些不能完全常量折叠的表达式在基数估计期间仍可能会进行某种折叠。
例如,可能产生错误的表达式不是常量折叠,但仍可以通过与选择性推导的一部分相同的机制进行评估。