Diyelim ki tek bir masam var
CREATE TABLE Ticket (
TicketId int NOT NULL,
InsertDateTime datetime NOT NULL,
SiteId int NOT NULL,
StatusId tinyint NOT NULL,
AssignedId int NULL,
ReportedById int NOT NULL,
CategoryId int NULL
);
Bu örnekte TicketIdBirincil Anahtar yer almaktadır.
Kullanıcıların bu tabloya karşı "kısmen geçici" sorgular oluşturabilmesini istiyorum. Kısmen diyorum çünkü sorgunun birkaç kısmı her zaman düzeltilecektir:
- Sorgu her zaman bir
InsertDateTime - Sorgu her zaman
ORDER BY InsertDateTime DESC - Sorgu, sonuçları gösterir
Kullanıcı isteğe bağlı olarak diğer sütunlardan herhangi birine filtre uygulayabilir. Hiçbirine, bir veya daha fazlasına filtre uygulayabilirler. Ve her sütun için kullanıcı, bir ayrılma olarak uygulanacak bir değer kümesi arasından seçim yapabilir. Örneğin:
SELECT
TicketId
FROM (
SELECT
TicketId,
ROW_NUMBER() OVER(ORDER BY InsertDateTime DESC) as RowNum
FROM Ticket
WHERE InsertDateTime >= '2013-01-01' AND InsertDateTime < '2013-02-01'
AND StatusId IN (1,2,3)
AND (CategoryId IN (10,11) OR CategoryId IS NULL)
) _
WHERE RowNum BETWEEN 1 AND 100;
Şimdi tablonun 100.000.000 satırı olduğunu varsayın.
Ben gelebilir en iyi "isteğe bağlı" sütunların her birini içeren bir kaplama dizinidir:
CREATE NONCLUSTERED INDEX IX_Ticket_Covering ON Ticket (
InsertDateTime DESC
) INCLUDE (
SiteId, StatusId, AssignedId, ReportedById, CategoryId
);
Bu bana aşağıdaki gibi bir sorgu planı verir:
- SEÇ
- filtre
- Üst
- Dizi Projesi (Hesaplamalı Skaler)
- bölüm
- Dizin Ara
- bölüm
- Dizi Projesi (Hesaplamalı Skaler)
- Üst
- filtre
Oldukça iyi görünüyor. Maliyetin yaklaşık% 80-% 90'ı ideal olan Endeks Arama işleminden gelir.
Bu tür bir araştırmayı uygulamak için daha iyi stratejiler var mı?
Isteğe bağlı filtreleme istemciye boşaltmak istemiyorum çünkü bazı durumlarda "sabit" bölümünden sonuç kümesi 100s veya 1000s olabilir. Bu durumda müşteri, müşteri için çok fazla işe yarayabilecek sıralama ve sayfalamadan da sorumlu olacaktır.
RowNum BETWEEN 101 AND 200?