Diciamo che ho un solo tavolo
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
);
In questo esempio TicketId
è la chiave primaria.
Voglio che gli utenti siano in grado di creare query "parzialmente ad hoc" su questa tabella. Dico in parte perché alcune parti della query verranno sempre corrette:
- La query eseguirà sempre un filtro intervallo su un
InsertDateTime
- La query sarà sempre
ORDER BY InsertDateTime DESC
- La query visualizzerà i risultati
L'utente può facoltativamente filtrare su una qualsiasi delle altre colonne. Possono filtrare su nessuno, uno o molti. E per ogni colonna l'utente può selezionare da una serie di valori che verranno applicati come disgiunzione. Per esempio:
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;
Ora supponiamo che la tabella abbia 100.000.000 di righe.
Il meglio che posso trovare è un indice di copertura che include ciascuna delle colonne "opzionali":
CREATE NONCLUSTERED INDEX IX_Ticket_Covering ON Ticket (
InsertDateTime DESC
) INCLUDE (
SiteId, StatusId, AssignedId, ReportedById, CategoryId
);
Questo mi dà un piano di query come segue:
- SELEZIONARE
- Filtro
- Superiore
- Progetto sequenza (Calcola scalare)
- Segmento
- Ricerca indice
- Segmento
- Progetto sequenza (Calcola scalare)
- Superiore
- Filtro
Sembra abbastanza buono. Circa l'80% -90% del costo deriva dall'operazione Index Seek, che è l'ideale.
Esistono strategie migliori per implementare questo tipo di ricerca?
Non voglio necessariamente scaricare il filtro opzionale sul client perché in alcuni casi il set di risultati dalla parte "fissa" potrebbe essere 100s o 1000s. Il client sarebbe quindi anche responsabile dell'ordinamento e del paging che potrebbero funzionare troppo per il client.
RowNum BETWEEN 101 AND 200
?