Während ich eine neue Abfrage bei der Arbeit entwickelte, schrieb ich sie und profilierte sie in SQL Query Analyzer. Die Abfrage war sehr gut ohne Tabellen-Scans, aber wenn ich es in einer gespeicherten Prozedur gekapselt hatte, war die Leistung schrecklich. Als ich den Ausführungsplan betrachtete, konnte ich sehen, dass SQL Server einen anderen Plan ausgewählt hatte, der einen Tabellenscan anstelle eines Indexsuchlaufs auf TableB verwendete (ich war gezwungen, die Tabellen- und Spaltennamen ein wenig zu verschleiern, aber keine der Abfragelogik hat sich verändert).Unterschiedlicher Ausführungsplan beim Ausführen der Anweisung direkt und aus der gespeicherten Prozedur
Hier ist die Abfrage
SELECT
DATEADD(dd, 0, DATEDIFF(dd, 0, TableA.Created)) AS Day,
DATEPART(hh, TableA.Created) AS [Hour],
SUM(TableB.Quantity) AS Quantity,
SUM(TableB.Amount) AS Amount
FROM
TableA
INNER JOIN TableB ON TableA.BID = TableB.ID
WHERE
(TableA.ShopId = @ShopId)
GROUP BY
DATEADD(dd, 0, DATEDIFF(dd, 0, TableA.Created)),
DATEPART(hh, TableA.Created)
ORDER BY
DATEPART(hh, TableA.Created)
Wenn ich die Abfrage ausführen „raw“ Ich erhalte die folgenden Trace-Statistik
Event Class Duration CPU Reads Writes SQL:StmtCompleted 75 41 7 0
Und wenn ich ausführen, um die Abfrage als eine gespeicherte Prozedur mit dem folgenden Befehl
Ich bekomme die folgenden Spur Statistiken
Event Class Duration CPU Reads Writes SQL:StmtCompleted 222 10 48 0
ich auch das gleiche Ergebnis, wenn ich die Abfrage in einer nvarchar speichern und ausführen Sp_executesql wie folgt aus (es führt wie die sproc)
DECLARE @SQL nvarchar(2000)
SET @SQL = 'SELECT DATEADD(dd, ...'
exec sp_executesql @SQL
Die gespeicherte Prozedur enthält nichts außer für die select-Anweisung oben. Was würde dazu führen, dass SQL Server einen untergeordneten Ausführungsplan auswählt, nur weil die Anweisung als gespeicherte Prozedur ausgeführt wird?
Wir laufen zur Zeit auf SQL Server 2000
Danke mann, das hat den Trick Kudos für die rötlich schnelle Antwort! –