Tiga SELECT
pernyataan dalam kode ini
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;
buat rencana ini:
Mengapa final SELECT
, yang memilih nilai yang bertahan, menghasilkan operator Compute Scalar ?
sql-server
sql-server-2008
execution-plan
Nick Chammas
sumber
sumber
[tempdb].[dbo].[persist_test].id
dan menghitung nilai meskipun tetap ada.Jawaban:
Hanya untuk meringkas temuan eksperimental dalam komentar ini tampaknya menjadi kasus tepi yang terjadi ketika Anda memiliki dua kolom yang dihitung dalam tabel yang sama, satu
persisted
dan satu tidak bertahan dan keduanya memiliki definisi yang sama.Dalam rencana kueri
Tabel memindai pada
persist_test
hanya memancarkanid
kolom. Komputasi skalar berikutnya bersama mengalikan bahwa dengan 5 dan menghasilkan kolom yang disebutid5
meskipun fakta bahwa kolom ini bahkan tidak direferensikan dalam kueri. Skalar komputasi akhir sepanjang mengambil nilaiid5
dan output yang disebut kolomid5p
.Menggunakan tanda jejak yang dijelaskan dalam Penyelidikan Dalam Query Optimizer - Bagian 2 (penafian: tanda ini tidak berdokumen / tidak didukung) dan melihat kueri
Memberikan hasilnya
Pohon Sebelum Normalisasi Proyek
Pohon Setelah Normalisasi Proyek
Jadi tampak bahwa semua definisi kolom yang dihitung diperluas kemudian selama tahap Normalisasi Proyek semua ekspresi yang identik dicocokkan kembali ke kolom yang dihitung dan kebetulan cocok dengan
id5
dalam kasus ini. yaitu tidak memberikan preferensi kepersisted
kolom.Jika tabel dibuat kembali dengan definisi berikut
Kemudian permintaan untuk salah satu
id5
atauid5p
akan puas dari membaca versi data yang bertahan daripada melakukan perhitungan saat runtime sehingga pencocokan tampaknya terjadi (setidaknya dalam kasus ini) dalam urutan kolom.sumber