Ich habe eine Abfrage, die eine Funktion für das Prädikat verwendet, ungefähr so:
commentType = 'EL'
AND commentDateTime >= DATEADD(month,datediff(month,0,getdate()) - 13,0)
Ich habe einen gefilterten Index für commentType mit 40 KB Zeilen. Wenn ich die Abfrage ausführe, ist die geschätzte Anzahl der Zeilen für die Indexsuche sehr genau (ca. 11 KB), aber für den nächsten Schritt (Sortieroperator) werden die Statistiken und vollständig ignoriert schätzt nur die Gesamtzahl der Zeilen im gefilterten Index.
Warum passiert dies? Ich kenne die Grundlagen der Sargabilität und habe sie nur aus Gründen der Vernunft getestet, indem ich das Datum durch ein aktuelles Datum (01.01.2014) und voila ersetzt habe ... Die Sortierung hat begonnen, die Anzahl der Zeilen richtig zu erraten ...
Warum passiert das und wie kann ich es beheben? Ich kann keinen festen Termin überschreiten ...
quelle
DATEADD(month,datediff(month,0,getdate()) - 13,0)
macht für mich keinen Sinn. Was versuchst du damit zu machen? Darf es verbessert / vereinfacht werden?DATEADD(month, -13, DATEADD(day, 1-DATEPART(day, SYSDATETIME()))
festzustellen, ob es einen Unterschied gibt?(commentType, commentDate)
, verhält er sich dort besser? Es ist nur so, dass gefilterte Indizes manchmal Schätzungen an verschiedenen Stellen in Plänen falsch melden können. Die Schätzung scheint ein Ausweg zu sein, wenn die Gesamtzahl im gefilterten Index angegeben wird, aber tatsächlich wird der Plan falsch angezeigt.Antworten:
Ich glaube, Ihre Schätzungen sind falsch, weil ein Schätzerfehler zwei der DATEDIFF-Argumente vertauscht. Ich spreche hier darüber:
Eine Problemumgehung besteht darin, den ersten Tag vor 13 Monaten ohne Verwendung von DATEDIFF (2008+) zu berechnen:
Ich bin nicht positiv , dass die Schätzung Adresse wird (ich habe nicht mit gefilterten Indizes getestet, und ich bin nicht sicher , was die Art tatsächlich tut oder warum es hat eine andere Schätzung ohne Plan und / oder den Rest der Abfrage ).
Das von Microsoft empfohlene Update ist die Verwendung von TF 4199, aber ich bin mir nicht sicher, ob Sie dies hier tun müssen:
Eine andere Möglichkeit wäre, sicherzustellen, dass Sie für jede Version von SQL Server, die Sie verwenden, auf dem absolut neuesten SP / CU sind, da dies im folgenden KB-Artikel behoben ist (obwohl hierfür weiterhin TF 4199 erforderlich ist es sei denn, Sie sind auf 2014 oder besser):
Das Update kann mit den folgenden Builds erhalten werden:
(Bitte geben Sie beim nächsten Mal die Ergebnisse von
SELECT @@VERSION
in Ihre Frage ein.)Ich werde bemerken, dass der KB-Artikel besagt, dass DATEDIFF die Anzahl der Zeilen unterschätzen kann , was das Gegenteil von dem ist, was in Ihrem Szenario passiert. Das bedeutet nicht, dass die Korrekturen nicht auf Sie zutreffen. Ich denke, der Wortlaut des KB-Artikels ist ungenau, da die Schätzungen je nach den Daten und dem Bereich, den Sie betrachten, in beide Richtungen gehen können.
Mein Blog-Beitrag oben hat bestätigt, dass der Austausch ab 2014 nicht mehr stattfindet. Um sicher zu gehen, würde ich wahrscheinlich nur DATEDIFF aus Ihrem Prädikat streichen und eine andere Methode verwenden, um den Beginn Ihres Bereichs zu berechnen. Ich empfehle nicht den Overkill von 4199 oder die Verwendung von dynamischem SQL, um den fehlerhaften Austausch zu verhindern.
quelle