Bu, Max Vernon'un çalışmalarını geliştirme çabasıdır . Çözümünde, görünümde 2 dizin ve bir istatistik nesnesi kullanmanızı önerir.
1. dizin kümelenir, bu da bir tablodaki kümelenmemiş bir dizinin aksine, görünümde kümelenmemiş bir dizinin oluşturulmasına ilk önce kümelenmiş bir dizin olmadan denenirse bir hata üretilir.
2. dizin, sorgunun arkasındaki dizin olarak kullanılan kümelenmemiş bir dizindir. Cevabının yorumlar bölümünde, kümelenmemiş bir dizin yerine kümelenmiş bir dizin kullanılırsa ne olacağını sordum.
Aşağıdaki analiz bu soruya cevap vermeye çalışmaktadır.
Görünümünde kümelenmemiş bir dizin oluşturmuyorum dışında, aynı kodu kullanıyorum.
Ayrıca bir istatistik nesnesi oluşturmuyorum. Aşağıdaki kodu izlemek için SQL Server Management Studio'yu (SSMS) takip ediyorsanız ve kullanıyorsanız, hatalara benzeyen bazı kırmızı dalgalı çizgiler gördüğünüzün farkında olmalısınız. Bunlar (muhtemelen) hata değildir, ancak akıllıca bir konuyu içerir.
Intellisense'i devre dışı bırakabilir veya sadece hataları yoksayabilir ve komutları çalıştırabilirsiniz. Hatasız tamamlamaları gerekir.
-- 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
Aşağıdaki sorgu planı (görünüm / dizin görünümü olmadan), aşağıdaki sorgu tabloya karşı çalıştırıldıktan sonra üretilir:
SELECT pv.PersistedViewTest_ID, pv.TestComputedColumn
FROM dbo.PersistedViewTest pv
WHERE pv.TestComputedColumn = CONVERT(INT, 26)
GO
Bu karşılaştırmak için bir taban çizgisi verir. Sorgu tamamlandıktan sonra bir istatistik nesnesi oluşturulduğuna dikkat edin (_WA_Sys_00000003_1FCDBCEB). Kümelenmiş tablo dizini oluşturulduğunda PK_PersistedViewTest istatistik nesnesi oluşturuldu.
Ardından, o görünümde filtrelenmiş görünüm ve kümelenmiş dizin oluşturulur:
-- 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
Şimdi, sorguyu tekrar çalıştırmayı deneyelim, ancak bu sefer görünüme karşı:
SELECT pv.PersistedViewTest_ID, pv.TestComputedColumn
FROM dbo.PersistedViewTest_View pv
WHERE pv.TestComputedColumn = CONVERT(INT, 26)
GO
Yeni yürütme planı şimdi:
Yeni plana inanılırsa, görünümün ve bu görünümde kümelenmiş dizinin eklenmesinden sonra, istatistikler sorguyu yürütmek için gereken sürenin iki katına çıktığını gösterir. Ayrıca, sorgu çalıştırıldıktan sonra tablodaki sorgudan farklı olan yeni dizini desteklemek için yeni bir istatistik nesnesinin oluşturulmadığına dikkat edin.
Sorgu planı, hâlâ kümelenmemiş bir dizin oluşturmanın, sorgunun performansını artırmada oldukça yardımcı olacağını göstermektedir. Bu, istenen performans iyileştirmesi sağlanmadan önce görünüme kümelenmemiş bir dizin eklenmesi gerektiği anlamına mı geliyor? Denenecek son bir şey var. "İLE NOEXPAND" seçeneğini kullanmak için sorguyu değiştirin:
SELECT pv.PersistedViewTest_ID, pv.TestComputedColumn
FROM dbo.PersistedViewTest_View pv WITH (NOEXPAND)
WHERE pv.TestComputedColumn = CONVERT(INT, 26)
GO
Bu, aşağıdaki sorgu planıyla sonuçlanır:
Bu yürütme planı, Max Vernon'un cevabında verilen kümelenmemiş endeks ile üretilen plana oldukça benziyor. Ancak, bu bir daha az (kümelenmemiş) dizin ve bir daha az istatistik nesnesiyle yapılır.
Dizine alınmış bir görünümden doğru şekilde yararlanmak için NOEXPAND seçeneğinin SQL Server'ın hızlı ve standart sürümleriyle kullanılması gerektiği ortaya çıktı. Paul White, NOEXPAND seçeneğini kullanmanın yararlarını anlatan mükemmel bir makaleye sahiptir. Ayrıca bu seçeneğin, görünüm dizinleri tarafından sağlanan benzersiz garantinin optimize edici tarafından kullanılmasını sağlamak için kurumsal sürümle birlikte kullanılmasını önerir .
Yukarıdaki analiz, SQL Sever 2014'ün ekspres sürümü ile yapıldı. SQL Server 2016'nın geliştirici sürümü ile de denedim. Performans kazanımlarını elde etmek için NOEXPAND seçeneğinin geliştirme sürümünde gerekli olmadığı görülüyor, ancak yine de önerilir .
5 aydan daha kısa bir süre önce Microsoft, geliştirici sürümlerini ücretsiz hale getirdi . Lisans, kullanımı yalnızca geliştirmeyle sınırlar, yani veritabanı bir üretim ortamında kullanılamaz. Bu nedenle, bellek için optimize edilmiş tabloları, şifrelemeyi, R'yi vb. Test etmek istiyorsanız, artık lisanssız mazeretin yok. Birkaç gün önce yanımda SQL Server 2014 Express ile sorunsuz bir şekilde bilgisayarıma başarıyla yükledim.
WHERE (sintMarketID = 2 AND strType = 'CARD' AND strTier1 LIKE 'GG%')
.