Ich habe eine Tabelle, und für einen bestimmten Satz von Feldern a, b und c muss ich die erste und letzte Zeile nach d und e sortieren und verwende ROW_NUMBER, um diese Zeilen abzurufen. Der relevante Teil der Erklärung ist ...
ROW_NUMBER() OVER (PARTITION BY a,b,c ORDER BY d ASC, e ASC) AS row_number_start,
ROW_NUMBER() OVER (PARTITION BY a,b,c ORDER BY d DESC, e DESC) AS row_number_end
Der Ausführungsplan zeigt zwei Sortiervorgänge, jeweils einen für jeden. Diese Sortiervorgänge machen über 60% der Gesamtkosten der Anweisung aus (wir sprechen hier von zig Millionen Zeilen, die Partitionen haben normalerweise 1-100 Datensätze pro Partition, meistens unter 10).
Es wäre also gut, wenn ich einen von ihnen loswerden könnte. Ich habe versucht, einen Index zu erstellen, um die Sortierung zu replizieren. Dies eliminierte eine der Sortieroperationen, aber nicht die letztere. (Beachten Sie, dass jeder erstellte Index nur für diesen Prozess von Nutzen ist und im Rahmen eines ETL-Prozesses täglich neu erstellt wird.)
Nach Prüfung des Ausführungsplans besteht das Problem meines Erachtens darin, dass SQL Server bei der Ausführung einer Partition nach Anweisung darauf besteht, die Reihenfolge der Partitionierungsspalten aufsteigend zu ändern. Logischerweise spielt es keine Rolle, ob Sie aufsteigend oder absteigend sortieren, und wenn der Optimierer dies verstanden hat, kann er denselben Index einfach rückwärts lesen, um row_number_end zu berechnen.
Gibt es eine Möglichkeit, den Optimierer hier sinnvoll zu machen, oder kann jemand einen alternativen Ansatz vorschlagen, um das gleiche Endziel zu erreichen?
quelle