เพียงเพื่อสรุปผลการทดลองในความคิดเห็นซึ่งเป็นกรณีขอบที่เกิดขึ้นเมื่อคุณมีคอลัมน์ที่คำนวณสองคอลัมน์ในตารางเดียวกันหนึ่งpersisted
และคอลัมน์หนึ่งที่ไม่ยืนยันและทั้งสองมีนิยามเดียวกัน
ในแผนสำหรับแบบสอบถาม
SELECT id5p
FROM dbo.persist_test;
การสแกนตารางpersist_test
จะปล่อยเฉพาะid
คอลัมน์ สเกลาร์การคำนวณถัดไปพร้อมกับคูณด้วย 5 และส่งออกคอลัมน์ที่เรียกว่าid5
แม้ว่าคอลัมน์นี้จะไม่ได้อ้างถึงในแบบสอบถาม เกลาคำนวณสุดท้ายพร้อมใช้เวลาค่าของและผลที่เป็นคอลัมน์ที่เรียกว่าid5
id5p
การใช้แฟล็กการติดตามที่อธิบายในQuery Optimizer Deep Dive - ส่วนที่ 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,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)
ต้นไม้หลังจากการทำให้เป็นปกติของโครงการ
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
ดังนั้นดูเหมือนว่าคำจำกัดความคอลัมน์ที่คำนวณทั้งหมดจะถูกขยายออกไปในระหว่างขั้นตอนการทำให้เป็นมาตรฐานของโครงการนิพจน์ที่เหมือนกันทั้งหมดจะถูกจับคู่กลับไปที่คอลัมน์ที่คำนวณแล้วและมันเกิดขึ้นเพื่อจับคู่id5
ในกรณีนี้ นั่นคือมันไม่ได้ให้การตั้งค่าใด ๆ กับpersisted
คอลัมน์
หากตารางถูกสร้างขึ้นใหม่ด้วยคำจำกัดความต่อไปนี้
CREATE TABLE dbo.persist_test (
id INT NOT NULL
, id5p AS (5 * id) PERSISTED
, id5 AS (5 * id)
);
จากนั้นคำขอสำหรับid5
หรือid5p
จะพอใจจากการอ่านข้อมูลที่เก็บไว้แทนการคำนวณที่รันไทม์ดังนั้นการจับคู่จะเกิดขึ้น (อย่างน้อยในกรณีนี้) ตามลำดับคอลัมน์
[tempdb].[dbo].[persist_test].id
และจะคำนวณค่าแม้จะยังคงอยู่