Lihat kueri ini. Ini cukup sederhana (lihat akhir posting untuk definisi tabel dan indeks, dan skrip repro):
SELECT MAX(Revision)
FROM dbo.TheOneders
WHERE Id = 1 AND 1 = (SELECT 1);
Catatan: "AND 1 = (PILIH 1) hanya untuk menjaga agar kueri ini tidak diparameterisasi secara otomatis, yang menurut saya membingungkan masalah - itu sebenarnya mendapatkan paket yang sama dengan atau tanpa klausa itu sekalipun
Dan inilah rencananya ( rekatkan tautan paket) :
Karena ada "top 1" di sana, saya terkejut melihat operator agregat aliran. Sepertinya tidak perlu bagi saya, karena dijamin hanya ada satu baris.
Untuk menguji teori itu, saya mencoba kueri yang setara secara logis ini:
SELECT MAX(Revision)
FROM dbo.TheOneders
WHERE Id = 1
GROUP BY Id;
Inilah paket untuk yang itu ( rekatkan tautan paket ):
Benar saja, grup berdasarkan rencana dapat bertahan tanpa operator agregat aliran.
Perhatikan bahwa kedua kueri membaca "mundur" dari akhir indeks dan lakukan "top 1" untuk mendapatkan revisi maksimal.
Apa yang kulewatkan di sini? Apakah agregat aliran benar-benar berfungsi di kueri pertama, atau haruskah itu dapat dihilangkan (dan itu hanya batasan pengoptimal yang bukan)?
Ngomong-ngomong, saya menyadari ini bukan masalah yang sangat praktis (kedua pertanyaan melaporkan 0 ms dari CPU dan waktu berlalu), saya hanya ingin tahu tentang internal / perilaku yang dipamerkan di sini.
Berikut kode pengaturan yang saya jalankan sebelum menjalankan dua pertanyaan di atas:
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