it-swarm.com.de

Unterschied zwischen Suchprädikat und Prädikat

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

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

(enter image description here

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 auf nichts davon.

12
Greg

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 Spalte PK. Es gibt einen nicht gruppierten Index für COL1, Der eine Schlüsselspalte von COL1 Hat und COL2 Enthält.

Betrachten Sie die folgende Abfrage:

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

Hier verwende ich nicht BETWEEN, weil Aaron Bertrand sich um diese Frage dreht.

Wie sollte SQL Server Optimizer diese Abfrage? Nun, ich weiß, dass der Filter für PK die 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 auf COL2 Anwenden. Hier ist PK ein Suchprädikat und COL2 Ein Prädikat.

(enter image description here

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:

(enter image description here

In diesem Fall kann SQL Server beide Spalten in der Klausel WHERE 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 COL1 Eine Schlüsselspalte. SQL Server kann mit dieser Spalte nach 1000 Zeilen mit einem übereinstimmenden Wert COL1 Suchen. Diese Zeilen in der Spalte COL2 Können weiter gefiltert werden, um die endgültige Ergebnismenge auf 0 Zeilen zu reduzieren.

(enter image description here

18
Joe Obbish