Unterschied zwischen Suchprädikat und Prädikat

12

Ich versuche, die Leistung einer Abfrage in SQL Server 2014 Enterprise zu optimieren.

Ich habe den eigentlichen Abfrageplan im SQL Sentry Plan Explorer geöffnet und kann auf einem Knoten sehen, dass er ein Suchprädikat und auch ein Prädikat hat

Was ist der Unterschied zwischen Suchprädikat und Prädikat ?

Geben Sie hier die Bildbeschreibung ein

Hinweis: Ich kann sehen, dass es mit diesem Knoten viele Probleme gibt (z. B. die Zeilen "Geschätzt" und "Ist", "Rest-E / A"), aber die Frage bezieht sich nicht auf irgendetwas davon.

Greg
quelle
3
Das Suchprädikat unterstützt den Join und filtert nur nach den Zeilen, die sich auch in der anderen Tabelle befinden (die Sie redigiert haben). Das Prädikat (ein Restprädikat) eliminiert dann die Zeilen mit dem spezifischen Status 2.
Aaron Bertrand
5
Rob Farley erklärte hier in einem Kommentar Folgendes :The Seek Predicate can be used to find the start of the RangeScan and then when to stop, while the Predicate is the "check" that is applied to every row in the Range.
Aaron Bertrand

Antworten:

18

Lassen Sie uns eine Million Zeilen zusammen mit einigen Spalten in eine temporäre Tabelle werfen:

CREATE TABLE #174860 (
PK INT NOT NULL, 
COL1 INT NOT NULL,
COL2 INT NOT NULL,
PRIMARY KEY (PK)
);

INSERT INTO #174860 WITH (TABLOCK)
SELECT RN
, RN % 1000
, RN % 10000
FROM 
(
    SELECT TOP 1000000 ROW_NUMBER () OVER (ORDER BY (SELECT NULL)) RN
    FROM   master..spt_values v1,
           master..spt_values v2
) t;

CREATE INDEX IX_174860_IX ON #174860 (COL1) INCLUDE (COL2);

Hier habe ich einen Clustered-Index (standardmäßig) für die PKSpalte. Es gibt einen nicht gruppierten Index COL1, der eine Schlüsselspalte von COL1und enthält COL2.

Betrachten Sie die folgende Abfrage:

SELECT *
FROM #174860
WHERE PK >= 15000 AND PK < 15005
AND COL2 = 5000;

Hier benutze ich nicht, BETWEENweil Aaron Bertrand um diese Frage herumhängt.

Wie sollte SQL Server Optimizer diese Abfrage? Nun, ich weiß, dass der Filter PKdie Ergebnismenge auf fünf Zeilen reduziert. SQL Server kann den Clustered-Index verwenden, um zu diesen fünf Zeilen zu springen, anstatt alle Millionen Zeilen in der Tabelle zu lesen. Der Clustered-Index enthält jedoch nur die PK-Spalte als Schlüsselspalte. Sobald die Zeile in den Speicher eingelesen ist, müssen wir den Filter anwenden COL2. Hier PKist ein Suchprädikat und COL2ist ein Prädikat.

Geben Sie hier die Bildbeschreibung ein

SQL Server findet fünf Zeilen unter Verwendung des Suchprädikats und reduziert diese fünf Zeilen mit dem normalen Prädikat auf eine Zeile.

Wenn ich den Clustered-Index anders definiere:

CREATE TABLE #174860 (
PK INT NOT NULL, 
COL1 INT NOT NULL,
COL2 INT NOT NULL,
PRIMARY KEY (COL2, PK)
);

Und führen Sie die gleiche Abfrage aus, ich erhalte unterschiedliche Ergebnisse:

Geben Sie hier die Bildbeschreibung ein

In diesem Fall kann SQL Server beide Spalten in der WHEREKlausel verwenden. Mit den Schlüsselspalten wird genau eine Zeile aus der Tabelle gelesen.

Betrachten Sie für ein weiteres Beispiel diese Abfrage:

SELECT *
FROM #174860
WHERE COL1 = 500
AND COL2 = 3545;

Der IX_174860_IX-Index ist ein Deckungsindex, da er alle für die Abfrage erforderlichen Spalten enthält. Es ist jedoch nur COL1eine Schlüsselspalte. SQL Server kann mit dieser Spalte suchen, um die 1000 Zeilen mit einem übereinstimmenden COL1Wert zu finden. Diese Zeilen in der COL2Spalte können weiter gefiltert werden , um die endgültige Ergebnismenge auf 0 Zeilen zu reduzieren.

Geben Sie hier die Bildbeschreibung ein

Joe Obbish
quelle