Katakanlah saya punya satu meja
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
);
Dalam contoh ini TicketIdadalah Kunci Utama.
Saya ingin pengguna dapat membuat kueri "sebagian ad-hoc" terhadap tabel ini. Saya katakan sebagian karena beberapa bagian dari query akan selalu diperbaiki:
- Kueri akan selalu melakukan filter rentang pada
InsertDateTime - Permintaan akan selalu
ORDER BY InsertDateTime DESC - Permintaan akan hasil halaman
Pengguna dapat memfilter secara opsional pada salah satu kolom lainnya. Mereka dapat memfilter tanpa, satu, atau banyak. Dan untuk setiap kolom pengguna dapat memilih dari serangkaian nilai yang akan diterapkan sebagai disjungsi. Sebagai contoh:
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;
Sekarang asumsikan tabel memiliki 100.000.000 baris.
Yang terbaik yang bisa saya dapatkan adalah indeks penutup yang mencakup masing-masing kolom "opsional":
CREATE NONCLUSTERED INDEX IX_Ticket_Covering ON Ticket (
InsertDateTime DESC
) INCLUDE (
SiteId, StatusId, AssignedId, ReportedById, CategoryId
);
Ini memberi saya rencana permintaan sebagai berikut:
- PILIH
- Saring
- Teratas
- Proyek Urutan (Hitung Skalar)
- Segmen
- Indeks mencari
- Segmen
- Proyek Urutan (Hitung Skalar)
- Teratas
- Saring
Sepertinya cukup bagus. Sekitar 80% -90% dari biaya berasal dari operasi Index Seek, yang ideal.
Adakah strategi yang lebih baik untuk menerapkan pencarian semacam ini?
Saya tidak perlu ingin melepas pemfilteran opsional ke klien karena dalam beberapa kasus hasil yang ditetapkan dari bagian "tetap" bisa 100s atau 1000s. Klien kemudian juga akan bertanggung jawab untuk menyortir dan paging yang mungkin terlalu banyak bekerja untuk klien.
RowNum BETWEEN 101 AND 200?