Nic*_*mas 21 sql-server-2008 sql-server execution-plan
SELECT这段代码中的三个语句
USE [tempdb];
GO
SET NOCOUNT ON;
CREATE TABLE dbo.persist_test (
id INT NOT NULL
, id5 AS (id * 5)
, id5p AS (id * 5) PERSISTED
);
INSERT INTO dbo.persist_test (id)
VALUES (1), (2), (3);
SELECT id
FROM dbo.persist_test;
SELECT id5
FROM dbo.persist_test;
SELECT id5p
FROM dbo.persist_test;
DROP TABLE dbo.persist_test;
Run Code Online (Sandbox Code Playgroud)
生成这个计划:

为什么SELECT选择持久值的 final生成计算标量运算符?
Mar*_*ith 15
只是为了总结评论中的实验结果,这似乎是一种边缘情况,当您在同一个表中有两个计算列时,一个persisted和一个没有持久化,并且它们都具有相同的定义。
在查询计划中
SELECT id5p
FROM dbo.persist_test;
Run Code Online (Sandbox Code Playgroud)
表扫描persist_test仅发出id列。下一个计算标量乘以 5 并输出一个名为的列,id5尽管该列在查询中甚至没有被引用。最终的计算标量采用 的值id5并将其输出为名为 的列id5p。
使用Query Optimizer Deep Dive – Part 2 中解释的跟踪标志(免责声明:这些跟踪标志未记录/不受支持)并查看查询
SELECT id5,
id5p,
( id * 5 )
FROM dbo.persist_test
OPTION (QUERYTRACEON 3604, QUERYTRACEON 8606);
Run Code Online (Sandbox Code Playgroud)
给出输出
项目规范化前的树
LogOp_Project
LogOp_Get TBL: dbo.persist_test dbo.persist_test TableID=1717581157 TableReferenceID=0 IsRow: COL: IsBaseRow1002
AncOp_PrjList
AncOp_PrjEl QCOL: [tempdb].[dbo].[persist_test].id5
ScaOp_Arithmetic x_aopMult
ScaOp_Identifier QCOL: [tempdb].[dbo].[persist_test].id
ScaOp_Const TI(int,ML=4) XVAR(int,Not Owned,Value=5)
AncOp_PrjEl QCOL: [tempdb].[dbo].[persist_test].id5p
ScaOp_Arithmetic x_aopMult
ScaOp_Identifier QCOL: [tempdb].[dbo].[persist_test].id
ScaOp_Const TI(int,ML=4) XVAR(int,Not Owned,Value=5)
AncOp_PrjEl COL: Expr1004
ScaOp_Arithmetic x_aopMult
ScaOp_Identifier QCOL: [tempdb].[dbo].[persist_test].id
ScaOp_Const TI(int,ML=4) XVAR(int,Not Owned,Value=5)
Run Code Online (Sandbox Code Playgroud)
项目规范化后的树
LogOp_Project
LogOp_Get TBL: dbo.persist_test dbo.persist_test TableID=1717581157 TableReferenceID=0 IsRow: COL: IsBaseRow1002
AncOp_PrjList
AncOp_PrjEl QCOL: [tempdb].[dbo].[persist_test].id5
ScaOp_Identifier QCOL: [tempdb].[dbo].[persist_test].id5
AncOp_PrjEl QCOL: [tempdb].[dbo].[persist_test].id5p
ScaOp_Identifier QCOL: [tempdb].[dbo].[persist_test].id5
AncOp_PrjEl COL: Expr1004
ScaOp_Identifier QCOL: [tempdb].[dbo].[persist_test].id5
Run Code Online (Sandbox Code Playgroud)
因此,所有计算列定义似乎都被扩展了,然后在项目规范化阶段,所有相同的表达式都匹配回计算列,并且id5在这种情况下恰好匹配。即它不给persisted列任何偏好。
如果使用以下定义重新创建表
CREATE TABLE dbo.persist_test (
id INT NOT NULL
, id5p AS (5 * id) PERSISTED
, id5 AS (5 * id)
);
Run Code Online (Sandbox Code Playgroud)
然后通过读取数据的持久版本而不是在运行时进行计算来满足对id5或的请求,id5p因此匹配似乎以列顺序发生(至少在这种情况下)。
| 归档时间: |
|
| 查看次数: |
7769 次 |
| 最近记录: |