Wie ist in SQL Server ...
Sp:
CREATE PROCEDURE insertToTable
@field1 VARCHAR(256), @field2 varchar(256), @field3 varchar(256)
AS
BEGIN
SET NOCOUNT ON
IF NOT EXISTS (SELECT * FROM my_table WHERE field1 = @field1)
INSERT INTO my_table
(field1, field2, field3)
VALUES (@field1, @field2, @field3);
ELSE
THROW 50000, 'xxxxxx', 1;
END
GO
Tabelle:
CREATE TABLE my_table (
field1 VARCHAR(256) NOT NULL,
field2 VARCHAR(256) NOT NULL,
field3 VARCHAR(256) NOT NULL
);
CREATE INDEX idx_field1 ON my_table(field1);
das oben schneller als das unten?
Sp:
CREATE PROCEDURE insertToTable
@field1 VARCHAR(256), @field2 varchar(256), @field3 varchar(256)
AS
BEGIN
SET NOCOUNT ON
INSERT INTO my_table
(field1, field2, field3)
VALUES (@field1, @field2, @field3);
GO
Tabelle:
CREATE TABLE my_table (
field1 VARCHAR(256) NOT NULL,
field2 VARCHAR(256) NOT NULL,
field3 VARCHAR(256) NOT NULL
);
CREATE UNIQUE INDEX idx_field1 ON my_table(field1);
Beispieleingabe:
Feld1: F56yCgZ9AEm9aFpTyjwhERtqNeglYEow Feld2: BD84CE2A514316164B7448C804B178AD8F6F597E8EC6F25F4D6E36287259C65F67E7206E82A4F8EFD2389C0821C0C70E8278DC5F166D220356B5A15A091A Feld 3: A18E9049117A77E6A4D41C6CA3FFDEA65D842BF1F57705405B4E66969531D93D
Die Eingabe wird im laufenden Betrieb von der Webanwendung und unter Verwendung vorbereiteter Anweisungen generiert. Ich verwende Jmeter, um Anfragen an meine Web-App zu generieren.
Mit dem UNIQUE
Index verschlechtert sich die Leistung der Einfügungen nach 100.000 Einfügungen und wird schlechter.
Mit dem NON UNIQUE
Index und einer manuellen Überprüfung mit IF NOT EXISTS SELECT
ist die Leistung auch bei Millionen eingefügter Datensätze konstant.
Die Werte sind so eindeutig, dass niemals ein Duplikat generiert wird. Auch nach einigen Millionen eingefügten Werten.
sql-server
index
user547
quelle
quelle
Antworten:
ENDGÜLTIGES UPDATE:
Es ist das INSERT, das die Dinge wirklich verlangsamt.
Wenn ein eindeutiger Index vorhanden ist, muss SQL bei jedem neuen Datensatz, den Sie hinzufügen, prüfen, ob der Wert bereits vorhanden ist. Wenn die Tabelle wächst, nimmt die Anzahl der Querverweise zu. Ein nicht eindeutiger Index erfordert keine Querverweise, sodass die Leistung konstant ist.
Eindeutige Indizes sind für SELECT-Anweisungen normalerweise schneller, dies ist jedoch mit Kosten verbunden, wenn eine Tabelle aktualisiert wird.
Im Folgenden wird erläutert, warum SELECT in einem eindeutigen Index manchmal langsamer sein kann
Ich habe Ihre Situation teilweise bis zu einem Punkt neu erstellt, an dem es meiner Meinung nach auf die Kombination von Parameter-Sniffing und SQL-Präferenzen mit dem NON-UNIQUE-Index auf einem HEAP zurückzuführen ist.
Richten Sie 2 Testtabellen ein, eine davon ist ein Heap (genau wie Ihre Tabelle).
Überprüfen Sie den Footprint der Indizes. Auf dem HEAP hat der UNIQUE-Index einen geringeren Footprint als der NON-UNIQUE-Index. (Möglicherweise enthalten die Seiten des NON-UNIQUE-Index zusätzliche - möglicherweise nützliche - Informationen.) (Hinweis: Nachdem Sie den obigen Code mehrmals ausgeführt haben, unterscheidet sich die Seitenzahl nicht, wahrscheinlich aufgrund von Caching. Ändern Sie den "GO 30000", um das Problem zu beheben Problem.)
Fragen Sie nun die Tabellen mit Literalen und Variablen ab.
Aus irgendeinem Grund bevorzugt SQL den NON UNIQUE-Index für einen HEAP, wenn SEEK-Operationen ausgeführt werden.
Hier ist, was ich denke, los ist. Wenn der nicht eindeutige Index mehr Seiten enthält, enthält das entsprechende Histogramm in den STATS mehr SCHRITTE. Führen Sie den folgenden Code aus.
Die zusätzlichen SCHRITTE erstellen eine detailliertere Ansicht des zugrunde liegenden Index, sodass der Optimierer (der weiß, dass EQ_ROWS immer 1 ist) eine bessere Kardinalitätsschätzung aus dem nicht eindeutigen Index erhält.
quelle