Sqlserver
 sql >> Datenbank >  >> RDS >> Sqlserver

Warum verlangsamt sich eine Abfrage drastisch, wenn in der WHERE-Klausel eine Konstante durch einen Parameter (mit demselben Wert) ersetzt wird?

Wie Martin in einem Kommentar unter der Frage angedeutet hat, besteht das Problem darin, dass der SQL-Server das Prädikat aus der WHERE-Klausel nicht richtig herunterdrückt - siehe den Link in seinem Kommentar.

Am Ende habe ich eine benutzerdefinierte Tabellenwertfunktion erstellt und sie mit dem CROSS APPLY-Operator zum Erstellen der Ansicht verwendet.

Sehen wir uns die Lösung selbst an.

Benutzerdefinierte Tabellenfunktion

CREATE FUNCTION [dbo].[TestFunction] (@Id INT)
RETURNS TABLE 
AS
RETURN 
(
    WITH
    Hierarchy (Id,  ParentId, Data, Depth)
    AS(
    SELECT Id, ParentId, NULL AS Data, 0 AS Depth FROM Test Where Id = @Id
    UNION ALL
    SELECT h.Id, t.ParentId, COALESCE(h.Data, t.Data), Depth + 1 AS Depth
        FROM Hierarchy h
            INNER JOIN Test t ON t.Id = h.ParentId
    )
    SELECT * FROM Hierarchy
)

Anzeigen

CREATE VIEW [dbo].[TestView]
AS
SELECT t.Id, t.ParentId, f.Data, f.Depth
FROM
    Test AS t
    CROSS APPLY TestFunction(Id) as f

Abfrage mit Konstante

SELECT * FROM TestView WHERE Id = 69

Abfrage mit Parameter

DECLARE @Id INT
SELECT @Id = 69
SELECT * FROM TestView WHERE Id = @Id

Die Abfrage mit dem Parameter wird grundsätzlich genauso schnell ausgeführt wie die Abfrage mit der Konstante.

Danke Martin und auch für die anderen!