Ini adalah upaya untuk meningkatkan pekerjaan Max Vernon . Dalam solusinya, ia menyarankan menggunakan 2 indeks pada tampilan dan objek statistik.
Indeks 1 dikelompokkan, yang sebenarnya diperlukan karena tidak seperti indeks nonclustered pada tabel, kesalahan akan dihasilkan jika pembuatan indeks nonclustered pada tampilan diupayakan tanpa terlebih dahulu memiliki indeks cluster.
Indeks ke-2 adalah indeks nonclustered, yang digunakan sebagai indeks di balik kueri. Di bagian komentar dari jawabannya, saya bertanya apa yang akan terjadi jika indeks berkerumun digunakan bukan indeks yang tidak dikelompokkan.
Analisis berikut mencoba menjawab pertanyaan ini.
Saya menggunakan kode yang sama persis, kecuali saya tidak membuat indeks nonclustered pada tampilan.
Saya juga tidak membuat objek statistik. Jika Anda mengikuti dan menggunakan SQL Server Management Studio (SSMS) untuk memasukkan kode di bawah ini, Anda harus sadar bahwa Anda mungkin melihat beberapa garis berlekuk merah - yang terlihat seperti kesalahan. Ini (mungkin) bukan kesalahan, tetapi melibatkan masalah dengan intellisense.
Anda dapat menonaktifkan intellisense atau mengabaikan kesalahan dan menjalankan perintah. Mereka harus menyelesaikan tanpa kesalahan.
-- Create the test table that uses a computed column.
USE tempdb;
CREATE TABLE dbo.PersistedViewTest
(
PersistedViewTest_ID INT NOT NULL
CONSTRAINT PK_PersistedViewTest
PRIMARY KEY CLUSTERED
IDENTITY(1,1)
, SomeData VARCHAR(2000) NOT NULL
, TestComputedColumn AS (PersistedViewTest_ID - 1) PERSISTED
);
GO
-- Insert some test data into the table.
INSERT INTO dbo.PersistedViewTest (SomeData)
SELECT o.name + o1.name + o2.name
FROM sys.objects o
CROSS JOIN sys.objects o1
CROSS JOIN sys.objects o2;
GO
Rencana eksekusi berikut (tanpa tampilan / tampilan indeks) dibuat setelah kueri berikut dijalankan terhadap tabel:
SELECT pv.PersistedViewTest_ID, pv.TestComputedColumn
FROM dbo.PersistedViewTest pv
WHERE pv.TestComputedColumn = CONVERT(INT, 26)
GO
Ini memberikan dasar untuk membandingkan. Perhatikan bahwa setelah kueri selesai, objek statistik dibuat (_WA_Sys_00000003_1FCDBCEB). Objek statistik PK_PersistedViewTest dibuat ketika indeks tabel berkerumun dibuat.
Selanjutnya, tampilan yang difilter dan indeks yang dikelompokkan pada tampilan tersebut dibuat:
-- Create filtered view on the computed column.
CREATE VIEW dbo.PersistedViewTest_View
WITH SCHEMABINDING
AS
SELECT PersistedViewTest_ID, SomeData, TestComputedColumn
FROM dbo.PersistedViewTest
WHERE TestComputedColumn < CONVERT(INT, 27);
GO
-- Create unique clustered index to persist the values, including the computed column.
CREATE UNIQUE CLUSTERED INDEX IX_PersistedViewTest
ON dbo.PersistedViewTest_View(PersistedViewTest_ID);
GO
Sekarang, mari kita coba jalankan kueri lagi, tapi kali ini bertentangan dengan pandangan:
SELECT pv.PersistedViewTest_ID, pv.TestComputedColumn
FROM dbo.PersistedViewTest_View pv
WHERE pv.TestComputedColumn = CONVERT(INT, 26)
GO
Rencana eksekusi baru sekarang:
Jika rencana baru dapat dipercaya, setelah penambahan tampilan dan indeks berkerumun pada tampilan itu, statistik muncul untuk menunjukkan bahwa waktu yang diperlukan untuk menjalankan kueri kini telah berlipat ganda. Juga, perhatikan bahwa tidak ada objek statistik baru yang dibuat untuk mendukung indeks baru setelah kueri dijalankan, yang berbeda dari kueri pada tabel.
Rencana kueri masih menyarankan bahwa pembuatan indeks yang tidak tercakup akan sangat membantu dalam meningkatkan kinerja kueri. Jadi, apakah itu berarti bahwa indeks nonclustered harus ditambahkan ke tampilan sebelum peningkatan kinerja yang diinginkan dapat diperoleh? Ada satu hal terakhir untuk dicoba. Ubah kueri untuk menggunakan opsi "WITH NOEXPAND":
SELECT pv.PersistedViewTest_ID, pv.TestComputedColumn
FROM dbo.PersistedViewTest_View pv WITH (NOEXPAND)
WHERE pv.TestComputedColumn = CONVERT(INT, 26)
GO
Ini menghasilkan rencana permintaan berikut:
Rencana eksekusi ini terlihat sangat mirip dengan yang dihasilkan dengan indeks nonclustered yang diberikan dalam jawaban Max Vernon. Tapi, ini dilakukan dengan satu indeks lebih sedikit (nonclustered) dan satu objek statistik kurang.
Ternyata opsi NOEXPAND harus digunakan dengan versi SQL Server express dan standar untuk memanfaatkan tampilan indeks. Paul White memiliki artikel bagus yang menguraikan manfaat menggunakan opsi NOEXPAND. Dia juga merekomendasikan opsi ini digunakan dengan edisi perusahaan untuk memastikan jaminan keunikan yang diberikan oleh indeks tampilan digunakan oleh pengoptimal.
Analisis di atas dilakukan dengan edisi ekspres SQL Sever 2014. Saya juga mencobanya dengan edisi pengembang SQL Server 2016. Opsi NOEXPAND tampaknya tidak diperlukan dengan edisi pengembangan untuk mencapai peningkatan kinerja, tetapi masih disarankan .
Kurang dari 5 bulan lalu, Microsoft membuat edisi pengembang gratis . Lisensi membatasi penggunaan hanya untuk pengembangan, yang berarti database tidak dapat digunakan dalam lingkungan produksi. Jadi, jika Anda mencari untuk menguji tabel yang dioptimalkan memori, enkripsi, R, dll. Maka Anda tidak lagi memiliki alasan tanpa lisensi. Saya berhasil menginstalnya di komputer saya beberapa hari yang lalu bersama SQL Server 2014 Express tanpa masalah.
WHERE (sintMarketID = 2 AND strType = 'CARD' AND strTier1 LIKE 'GG%')
.