sql-server – 当我选择一个持久的计算列时,为什么SQL Server“C
发布时间:2020-12-12 06:14:51 所属栏目:MsSql教程 来源:网络整理
导读:此代码中的三个SELECT语句 USE [tempdb];GOSET 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 idFROM dbo.persist_test;SELECT id5
此代码中的三个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; 生成这个计划: 为什么选择持久值的最终SELECT生成一个Compute Scalar运算符? 解决方法只是为了总结评论中的实验结果,这似乎是一个边缘情况,当你在同一个表中有两个计算列时,一个持久化,一个不持久,并且它们都具有相同的定义.在查询计划中 SELECT id5p FROM dbo.persist_test; 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); 给出输出 项目规范化之前的树 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,Value=5) AncOp_PrjEl COL: Expr1004 ScaOp_Arithmetic x_aopMult ScaOp_Identifier QCOL: [tempdb].[dbo].[persist_test].id ScaOp_Const TI(int,Value=5) 项目规范化后的树 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 因此,似乎所有计算列定义都被扩展,然后在Project Normalization阶段期间,所有相同的表达式都匹配回计算列,在这种情况下它恰好匹配id5.即它没有给持久列提供任何偏好. 如果使用以下定义重新创建表 CREATE TABLE dbo.persist_test ( id INT NOT NULL,id5p AS (5 * id) PERSISTED,id5 AS (5 * id) ); 然后,通过读取持久化版本的数据而不是在运行时进行计算,将满足对id5或id5p的请求,因此匹配似乎按列顺序发生(至少在这种情况下). (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |