Diese Abfrage wird in ~ 21 Sekunden ausgeführt ( Ausführungsplan ):
select
a.month
, count(*)
from SubqueryTest a
where a.year = (select max(b.year) from SubqueryTest b)
group by a.month
Wenn die Unterabfrage durch eine Variable ersetzt wird, wird sie in <1 Sekunde ausgeführt ( Ausführungsplan ):
declare @year float
select @year = max(b.year) from SubqueryTest b
select
month
, count(*)
from SubqueryTest where year = @year group by month
Nach dem Ausführungsplan zu urteilen, wird die Unterauswahl "select max ..." für jede der Millionen Zeilen in "SubqueryTest a:" ausgeführt, weshalb es so lange dauert.
Meine Frage: Da die Unterauswahl skalar, deterministisch und nicht korreliert ist, warum macht der Abfrageoptimierer nicht das, was ich in meinem zweiten Beispiel getan habe, und führt die Unterabfrage einmal aus, speichert das Ergebnis und verwendet es dann für die Hauptabfrage? Ich bin mir sicher, dass mein Verständnis von SQL Server nur eine Lücke aufweist, aber ich würde wirklich gerne beim Ausfüllen helfen - ein paar Stunden mit Google haben nicht geholfen.
Die Tabelle ist etwas mehr als 1 GB mit fast 28 Millionen Datensätzen:
CREATE TABLE SubqueryTest(
[pk_id] [int] IDENTITY(1,1) NOT NULL
, [Year] [float] NULL
, [Month] [float] NULL PRIMARY KEY CLUSTERED ([pk_id] ASC))
CREATE NONCLUSTERED INDEX idxSubqueryTest ON SubqueryTest ([Year] ASC)
Year
als Schwimmer haben. Sorry, nein, das macht für Stardates Sinn . AberMonth
als Schwimmer? Wirft mich wirklich auf.