2011-01-13 7 views
0

Ich bekomme etwas komisch. i lief diese sql:wie das passiert SP sql server

SELECT Id , GameTypeId , PlayerId , BetAmount , Profit , 
     DateAndTime 
FROM  Results 
WHERE DateAndTime >= DATEADD (DAY , -1 , SYSDATETIME()) 
     AND 
     DateAndTime < SYSDATETIME() 
ORDER BY DateAndTime ASC; 

i Nicht-Cluster-Index auf der Datumsspalte
und die tatsächliche Anzahl der Zeilen, die Rückkehr ist
672 Reihe von 1.600.016 Zeilen in der Tabelle. (die geschätzte Reihe war 1)

nach, dass ich diese SQL-Rennen:

declare @d DATETIME2(7) 
set @d = DATEADD (DAY , -1 , SYSDATETIME()) 
declare @d2 DATETIME2(7) 
set @d2 = SYSDATETIME() 

SELECT Id , GameTypeId , PlayerId , BetAmount , Profit , 
     DateAndTime 
FROM  Results 
WHERE DateAndTime >= @d 
     AND 
     DateAndTime < @d2 
ORDER BY DateAndTime ASC; 

und die tatsächlichen Ausführungsplan TABLE SCANE war !!! und die tatsächliche Anzahl der Zeilen, die zurückgegeben werden, ist
672 Zeile von 1600016 Zeilen in der Tabelle. (die geschätzte Zeile war 144000 r0ws)

einige 1 wissen, was hier passiert ist?!?!?

+0

Führen Sie 'SET SHOWPLAN_TEXT ON' aus und geben Sie genaue Ausführungspläne für beide Abfragen ein. – Quassnoi

+0

Am besten ersetzen Sie den letzten Satz der Frage durch "Weiß jemand, was hier passiert ist und wie man den Tabellenscan vermeidet?" –

Antwort

0

Wenn die Anzahl der geschätzten Zeilen sehr hoch ist, kommt das Optimierungsprogramm zu dem Schluss, dass eine vollständige Tabellensuche möglicherweise effektiver ist als eine Indexsuche + RID-Suche.

Also, die Frage ist, warum die Anzahl der geschätzten Zeilen weg ist?

Ich bin leider noch nicht so tief in SQL Server. Allerdings würde ich sagen, das liegt an den Bindeparametern; das kann die Kardinalitätsschätzungen (Schätzungszeilen) ziemlich stark beeinflussen (zumindest in anderen Datenbanken).

4

Da Sie Variablen für Ihre Werte verwenden, weiß der Abfrageoptimierer nicht, wie selektiv Ihre WHERE-Klausel ist, und entscheidet sich für einen Tabellenscan. Versuchen Sie, einen Clustered-Index für Ihr DateAndTime-Feld zu erstellen.

+1

Variablen - keine Parameter. Der Wert von Variablen ist zur Kompilierzeit nicht bekannt. 'OPTION (RECOMPILE)' kann helfen. –

+0

habe ich das verstanden.Aber gibt es eine Möglichkeit, dem Optimierer zu sagen, dass er die Abfrage bei jedem Durchlauf neu kompilieren muss oder was kann ich in diesem Fall tun, wenn ich viel Argument in den Variablen bekommen kann? – dani

+1

Variablen in der Tat, korrigiert! –

2

Versuchen

declare @d DATETIME2(7) 
set @d = DATEADD (DAY , -1 , SYSDATETIME()) 
declare @d2 DATETIME2(7) 
set @d2 = SYSDATETIME() 

SELECT Id , GameTypeId , PlayerId , BetAmount , Profit , 
     DateAndTime 
FROM  Results 
WHERE DateAndTime >= @d 
     AND 
     DateAndTime < @d2 
ORDER BY DateAndTime ASC 
OPTION (RECOMPILE); 

Dies wird den Plan für die Anweisung, sobald der Wert der Variablen sind bekannt und so ermöglichen eine genaue Kardinalitätsschätzungen verwendet werden neu kompilieren. Wenn Sie wissen, dass Sie immer einen sehr kleinen Prozentsatz auswählen, könnten Sie einfach den FORCESEEK Hinweis (if SQL Server 2008) verwenden, um die Rekompilierung zu vermeiden, aber die Verwendung dieses Hinweises kann katastrophal für größere Bereiche sein wegen der Anzahl der Schlüsselsuchen!

1

Neben Martin Antwort ...

Results.DateAndTime sollte datetime2 (7) auch gemäß den Variablen sein. Wenn nicht, haben Sie höchstwahrscheinlich eine Priorität des Datentyps

0

Ich habe festgestellt, dass, wenn die geschätzte Anzahl der Zeilen erheblich von der tatsächlichen Zahl abweicht, entweder Statistiken fehlen oder die Statistiken, die Sie haben, nicht vorhanden sind Datum. Sie sollten in der Lage sein, einen Abfrageplan in SSMS zu betrachten und basierend auf Kardinalitätsschätzungen für die verschiedenen Operatoren herauszufinden, welche Statistiken fehlen oder veraltet sind.

Verwandte Themen