Dai un'occhiata a questa domanda. È piuttosto semplice (vedere la fine del post per le definizioni di tabelle e indici e uno script di repro):
SELECT MAX(Revision)
FROM dbo.TheOneders
WHERE Id = 1 AND 1 = (SELECT 1);
Nota: "AND 1 = (SELEZIONA 1) serve solo a impedire che questa query venga parametrizzata automaticamente, cosa che mi sembrava confondere il problema - in realtà ottiene lo stesso piano con o senza quella clausola
Ed ecco il piano ( incolla il link del piano) :
Dato che c'è un "top 1" lì, sono stato sorpreso di vedere l'operatore di aggregazione del flusso. Non mi sembra necessario, poiché è garantito che ci sia solo una riga.
Per testare questa teoria, ho provato questa query logicamente equivalente:
SELECT MAX(Revision)
FROM dbo.TheOneders
WHERE Id = 1
GROUP BY Id;
Ecco il piano per quello ( incolla il link del piano ):
Abbastanza sicuro, il gruppo per piano è in grado di cavarsela senza l'operatore aggregato di flusso.
Si noti che entrambe le query leggono "indietro" dalla fine dell'indice ed eseguono un "primo 1" per ottenere la revisione massima.
Cosa mi sto perdendo qui? L'aggregato di flusso sta effettivamente funzionando nella prima query o dovrebbe essere in grado di essere eliminato (ed è solo una limitazione dell'ottimizzatore che non lo è)?
A proposito, mi rendo conto che questo non è un problema incredibilmente pratico (entrambe le query riportano 0 ms di CPU e tempo trascorso), sono solo curioso di vedere gli interni / il comportamento qui esposti.
Ecco il codice di installazione che ho eseguito prima di eseguire le due query sopra:
DROP TABLE IF EXISTS dbo.TheOneders;
GO
CREATE TABLE dbo.TheOneders
(
Id INT NOT NULL,
Revision SMALLINT NOT NULL,
Something NVARCHAR(23),
CONSTRAINT PK_TheOneders PRIMARY KEY NONCLUSTERED (Id, Revision)
);
GO
INSERT INTO dbo.TheOneders
(Id, Revision, Something)
SELECT DISTINCT TOP 1000
1, m.message_id, 'Do...'
FROM sys.messages m
ORDER BY m.message_id
OPTION (MAXDOP 1);
INSERT INTO dbo.TheOneders
(Id, Revision, Something)
SELECT DISTINCT TOP 100
2, m.message_id, 'Do that thing you do...'
FROM sys.messages m
ORDER BY m.message_id
OPTION (MAXDOP 1);
GO