2010-10-19 8 views
6

Beispielabfrage:Warum läuft die parametrisierte Version dieser Abfrage langsamer als eine nicht parametrisierte Version?

CREATE PROCEDURE dbo.Test (@p varchar(10)) 
AS 
DECLARE @param varchar(10) 
SET @param = @p + '%' 

SELECT * FROM table1 t1 
INNER JOIN table2 t2 on t1.id = tr.id 
WHERE t2.desc LIKE @param 

Ich habe eine Abfrage, die auf eine ähnliche ist oben, und wenn ich diese Prozedur in gespeichert verwenden es läuft auf unbestimmte Zeit ohne jegliche Ausgabe zu geben. Aber wenn ich dieselbe Abfrage wie verwende,

SELECT * FROM table1 t1 
INNER JOIN table2 t2 on t1.id = tr.id 
WHERE t2.desc LIKE 'A%' -- notice no parameter here 

Dies wird in weniger als einer Sekunde ausgeführt.

Mein table2 hat 140K Aufzeichnungen und tabelle1 einige 250K

Jede Idee, was wie Betreiber verursachen könnte langsam laufen?

+0

Haben Sie sich einen Erklärungsplan für die Abfrage angesehen? –

+0

Aufgrund Ihrer Tests klingt es nicht so, als hätte es überhaupt etwas mit dem gleichen Schlüsselwort zu tun, da sogar die schnelle Version diesen Operator enthält. – JohnFx

+0

Ich habe versucht, beide laufen und es läuft weniger als eine Sekunde, wenn ich Parameter direkt verwende. –

Antwort

4

Es weiß nicht zur Kompilierzeit, dass @param keinen führenden Platzhalter haben wird. Wenn es also den Stapel kompiliert, gibt es einen Plan mit einem Scan, kein Suchvorgang.

Sie könnten versuchen OPTION (RECOMPILE) oder OPTION (FORCESEEK) (SQL Server 2008), um zu sehen, ob es Ihnen einen besseren Plan gibt.

+0

+1 und danke, dass Sie mich direkt auf die lokale Variable setzen. –

+0

OPTION (RECOMPILE) gearbeitet. Jetzt läuft es weniger als eine Sekunde. Meine ursprüngliche Abfrage hat 4 innere Joins und 3 linke äußere Joins. –

+0

@rs - Nachdem ich einige Tests gemacht habe, fange ich an, meine Erklärung zu bezweifeln. Wenn ich mir den Stored-Procedure-Plan ansehe, sehe ich, dass beide mit einem Index-Range-Search enden. Die parametrisierte Version hat einen Rechen-Skalaroperator, der 'LikeRangeStart' und' LikeRangeEnd' aufruft. Es verwendet diesen Bereichssuchvorgang sogar dann, wenn ein führender Platzhalter vorhanden ist. Wie sehen Ihre Ausführungspläne aus? Fraglich, ob Kollationierung etwas bewirken kann (oder vielleicht ist es nur eine Frage der verzerrten Statistik, was bedeutet, dass sie die Reihenfolge der Operatoren verändert). –

Verwandte Themen