Asynchrone Indizes in Aurora DSQL
Der CREATE INDEX ASYNC-Befehl erstellt einen Index für eine oder mehrere Spalten einer vorgegebenen Tabelle. Dieser Befehl ist ein asynchroner DDL-Vorgang, der andere Transaktionen nicht blockiert. Wenn Sie CREATE INDEX ASYNC ausführen, gibt Aurora DSQL sofort eine job_id zurück.
Sie können den Status dieses asynchronen Auftrags mithilfe der sys.jobs-Systemansicht überwachen. Während der Indexerstellungsauftrag ausgeführt wird, können Sie die folgenden Verfahren und Befehle verwenden:
sys.wait_for_job(job_id)'your_index_creation_job_id'-
Blockiert die aktuelle Sitzung, bis der angegebene Auftrag abgeschlossen ist oder fehlschlägt. Gibt einen Booleschen Wert zurück, der Erfolg oder Misserfolg anzeigt.
DROP INDEX-
Bricht einen aktiven Index-Erstellungsjob ab.
Wenn die asynchrone Indexerstellung abgeschlossen ist, aktualisiert Aurora DSQL den Systemkatalog, um den Index als aktiv zu kennzeichnen.
Anmerkung
Beachten Sie, dass bei gleichzeitigen Transaktionen, die während dieser Aktualisierung auf Objekte im selben Namespace zugreifen, Parallelitätsfehler auftreten können.
Wenn Aurora DSQL eine asynchrone Indexaufgabe beendet, aktualisiert es den Systemkatalog, um zu zeigen, dass der Index aktiv ist. Wenn andere Transaktionen zu diesem Zeitpunkt auf die Objekte im selben Namespace verweisen, wird möglicherweise ein Parallelitätsfehler angezeigt.
Syntax
CREATE INDEX ASYNC verwendet die folgende Syntax:
CREATE [ UNIQUE ] INDEX ASYNC [ IF NOT EXISTS ] name ON table_name ( { column_name } [ NULLS { FIRST | LAST } ] ) [ INCLUDE ( column_name [, ...] ) ] [ NULLS [ NOT ] DISTINCT ]
Parameter
UNIQUE-
Weist Aurora DSQL an, bei der Indexerstellung und bei jedem Hinzufügen von Daten nach doppelten Werten in der Tabelle zu suchen. Wenn Sie diesen Parameter angeben, wird bei Einfüge- und Aktualisierungsvorgängen, die zu doppelten Einträgen führen würden, ein Fehler generiert.
IF NOT EXISTS-
Zeigt an, dass Aurora DSQL keine Ausnahme auslösen soll, wenn bereits ein Index mit demselben Namen vorhanden ist. In dieser Situation erstellt Aurora DSQL den neuen Index nicht. Beachten Sie, dass der Index, den Sie zu erstellen versuchen, eine ganz andere Struktur als der bereits vorhandene Index haben kann. Wenn Sie diesen Parameter vorgeben, muss der Indexname angegeben werden.
name-
Der Indexname. Sie können den Namen Ihres Schemas nicht in diesen Parameter aufnehmen.
Aurora DSQL erstellt den Index im gleichen Schema wie die übergeordnete Tabelle. Der Name der Ansicht muss sich von den Namen aller anderen Objekte (z. B. Tabelle, Index, Ansicht) im selben Schema unterscheiden.
Wenn Sie keinen Namen angeben, generiert Aurora DSQL automatisch einen Namen, der auf dem Namen der übergeordneten Tabelle und der indizierten Spalte basiert. Wenn Sie beispielsweise
CREATE INDEX ASYNC on table1 (col1, col2)ausführen, nennt Aurora DSQL den Index automatischtable1_col1_col2_idx. NULLS FIRST | LAST-
Die Sortierreihenfolge von NULL- und Nicht-NULL-Spalten:
FIRSTgibt an, dass Aurora DSQL NULL-Spalten vor Nicht-NULL-Spalten sortieren soll.LASTbedeutet, dass Aurora DSQL NULL-Spalten nach Nicht-NULL-Spalten sortiert. INCLUDE-
Eine Liste von Spalten, die im Index als Nicht-Schlüsselspalten enthalten sein sollen. Nicht-Schlüsselspalten können nicht in einer Index-Scan-Suchbedingung verwendet werden. Aurora DSQL ignoriert die Spalte im Hinblick auf die Eindeutigkeit eines Index.
NULLS DISTINCT | NULLS NOT DISTINCT-
Legt fest, ob Aurora DSQL NULL-Werte in einem eindeutigen Index als eindeutig behandeln soll. Standardmäßig gilt
DISTINCT, was bedeutet, dass ein eindeutiger Index mehrere NULL-Werte in einer Spalte enthalten darf.NOT DISTINCThingegen gibt an, dass ein Index keine mehrfachen NULL-Werte in einer Spalte zulassen darf.
Nutzungshinweise
Berücksichtigen Sie die folgenden Hinweise:
-
Der
CREATE INDEX ASYNC-Befehl führt keine Sperren ein. Er hat auch keinen Einfluss auf die Basistabelle, die Aurora DSQL verwendet, um den Index zu erstellen. -
Bei Schemamigrationsvorgängen ist das
sys.wait_for_job(job_id)-Verfahren nützlich. Es stellt sicher, dass nachfolgende DDL- und DML-Operationen auf den neu erstellten Index abzielen.'your_index_creation_job_id' -
Jedes Mal, wenn Aurora DSQL eine neue asynchrone Aufgabe ausführt, überprüft es die
sys.jobs-Ansicht und löscht Aufgaben, die einen Status voncompletedoder länger alsfailed30 Minuten haben.sys.jobszeigt also hauptsächlich Aufgaben an, die gerade bearbeitet werden, und enthält keine Informationen über alte Aufgaben. -
Wenn Aurora DSQL keinen asynchronen Index erstellen kann, bleibt der Index
INVALID. Bei eindeutigen Indizes unterliegen DML-Operationen Eindeutigkeitsbeschränkungen, bis Sie den Index löschen. Es wird empfohlen, ungültige Indizes zu löschen und sie neu zu erstellen.
Erstellen eines Index: Beispiel
Im folgenden Beispiel wird gezeigt, wie Sie ein Schema, eine Tabelle und dann einen Index erstellen.
-
Erstellen Sie eine Tabelle mit dem Namen
test.departments.CREATE SCHEMA test; CREATE TABLE test.departments (name varchar(255) primary key NOT null, manager varchar(255), size varchar(4)); -
Fügen Sie eine Zeile in die Tabelle ein.
INSERT INTO test.departments VALUES ('Human Resources', 'John Doe', '10') -
Erstellen Sie einen asynchronen Index.
CREATE INDEX ASYNC test_index on test.departments(name, manager, size);Der Befehl
CREATE INDEXgibt eine Auftrags-ID zurück, wie im Folgenden dargestellt.job_id -------------------------- jh2gbtx4mzhgfkbimtgwn5j45yjob_idzeigt an, dass Aurora DSQL einen neuen Auftrag zur Indexerstellung eingereicht hat. Sie können das Verfahrensys.wait_for_job(job_id)verwenden, um andere Arbeiten an der Sitzung zu blockieren, bis der Auftrag abgeschlossen ist oder ein Timeout eintritt.'your_index_creation_job_id'
Abfragen des Indexerstellungsstatus: Beispiel
Fragen Sie die Systemansicht sys.jobs ab, um den Erstellungsstatus Ihres Index zu überprüfen, wie im folgenden Beispiel gezeigt:
SELECT * FROM sys.jobs
Aurora DSQL gibt eine Antwort zurück, die in etwa wie folgt aussieht:
job_id | status | details ----------------------------+------------+--------- vs3kcl3rt5ddpk3a6xcq57cmcy | completed | ihbyw2aoirfnrdfoc4ojnlamoq | processing |
Die Statusspalte kann einen der folgenden Werte enthalten:
submitted |
processing |
failed |
completed |
|---|---|---|---|
| Die Aufgabe wurde eingereicht, aber Aurora DSQL hat noch nicht mit der Verarbeitung begonnen. | Aurora DSQL verarbeitet die Aufgabe. | Die Aufgabe ist fehlgeschlagen. Weitere Informationen finden Sie in der Detailspalte. Wenn Aurora DSQL den Index nicht erstellen konnte, wird Aurora DSQL die Indexdefinition nicht automatisch entfernen. Sie müssen den Index manuell mit dem Befehl DROP INDEX entfernen. |
Aurora DSQL |
Sie können den Indexstatus auch über die Katalogtabellen pg_index und pg_class abfragen. Insbesondere die Attribute indisvalid und indisimmediate geben Aufschluss über den aktuellen Indexstatus. Wenn Aurora DSQL Ihren Index erstellt, hat dieser zunächst den Status INVALID. Das indisvalid-Flag für den Index gibt FALSE oder f zurück, was darauf hinweist, dass der Index ungültig ist. Wenn das Flag TRUE oder t zurückgibt, ist der Index bereit.
SELECT relname AS index_name, indisvalid as is_valid, pg_get_indexdef(indexrelid) AS index_definition from pg_index, pg_class WHERE pg_class.oid = indexrelid AND indrelid = 'test.departments'::regclass;
index_name | is_valid | index_definition ------------------+----------+------------------------------------------------------------------------------------------------------------------- department_pkey | t | CREATE UNIQUE INDEX department_pkey ON test.departments USING btree_index (title) INCLUDE (name, manager, size) test_index1 | t | CREATE INDEX test_index1 ON test.departments USING btree_index (name, manager, size)
Fehler beim Erstellen eines eindeutigen Indexes
Wenn Ihr asynchroner Job zum Erstellen eines eindeutigen Indexes den Status FAILED mit dem Detail Found duplicate key while validating index for UCVs anzeigt, bedeutet dies, dass der eindeutige Index aufgrund von Verstößen gegen die Eindeutigkeitsbedingung nicht erstellt werden konnte.
So beheben Sie Fehler beim Erstellen eines eindeutigen Indexes
-
Entfernen Sie alle Zeilen in Ihrer Primärtabelle, die doppelte Einträge für die in Ihrem eindeutigen sekundären Index angegebenen Schlüssel enthalten.
-
Löschen Sie den fehlgeschlagenen Index.
-
Geben Sie einen neuen Befehl zum Erstellen eines Index ein.
So erkennen Sie Eindeutigkeitsverstöße in Primärtabellen
Die folgende SQL-Abfrage hilft Ihnen bei der Identifizierung von doppelten Werten in einer bestimmten Spalte Ihrer Tabelle. Dies ist besonders nützlich, wenn Sie Eindeutigkeit für eine Spalte erzwingen möchten, die derzeit nicht als Primärschlüssel definiert ist oder keine eindeutige Einschränkung besitzt – etwa bei E-Mail-Adressen in einer Benutzertabelle.
In den folgenden Beispielen wird demonstriert, wie Sie eine Beispielbenutzertabelle erstellen, sie mit Testdaten füllen, die bekannte Duplikate enthalten, und dann die Erkennungsabfrage ausführen.
Tabellenschema definieren
-- Drop the table if it exists DROP TABLE IF EXISTS users; -- Create the users table with a simple integer primary key CREATE TABLE users ( user_id INTEGER PRIMARY KEY, email VARCHAR(255), first_name VARCHAR(100), last_name VARCHAR(100), created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP );
Fügen Sie Beispieldaten ein, die Sätze doppelter E-Mail-Adressen enthalten
-- Insert sample data with explicit IDs INSERT INTO users (user_id, email, first_name, last_name) VALUES (1, 'john.doe@example.com', 'John', 'Doe'), (2, 'jane.smith@example.com', 'Jane', 'Smith'), (3, 'john.doe@example.com', 'Johnny', 'Doe'), (4, 'alice.wong@example.com', 'Alice', 'Wong'), (5, 'bob.jones@example.com', 'Bob', 'Jones'), (6, 'alice.wong@example.com', 'Alicia', 'Wong'), (7, 'bob.jones@example.com', 'Robert', 'Jones');
Führen Sie eine Abfrage zur Erkennung doppelter Objekte aus
-- Query to find duplicates WITH duplicates AS ( SELECT email, COUNT(*) as duplicate_count FROM users GROUP BY email HAVING COUNT(*) > 1 ) SELECT u.*, d.duplicate_count FROM users u INNER JOIN duplicates d ON u.email = d.email ORDER BY u.email, u.user_id;
Zeigen Sie alle Datensätze mit doppelten E-Mail-Adressen an
user_id | email | first_name | last_name | created_at | duplicate_count ---------+------------------------+------------+-----------+----------------------------+----------------- 4 | akua.mansa@example.com | Akua | Mansa | 2025-05-21 20:55:53.714432 | 2 6 | akua.mansa@example.com | Akua | Mansa | 2025-05-21 20:55:53.714432 | 2 1 | john.doe@example.com | John | Doe | 2025-05-21 20:55:53.714432 | 2 3 | john.doe@example.com | Johnny | Doe | 2025-05-21 20:55:53.714432 | 2 (4 rows)
Wenn wir die Anweisung zur Indexerstellung jetzt ausprobieren würden, würde sie fehlschlagen:
postgres=> CREATE UNIQUE INDEX ASYNC idx_users_email ON users(email); job_id ---------------------------- ve32upmjz5dgdknpbleeca5tri (1 row) postgres=> select * from sys.jobs; job_id | status | details | job_type | class_id | object_id | object_name | start_time | update_time ----------------------------+-----------+-----------------------------------------------------+-------------+----------+-----------+------------------------+------------------------+------------------------ qpn6aqlkijgmzilyidcpwrpova | completed | | DROP | 1259 | 26384 | | 2025-05-20 00:47:10+00 | 2025-05-20 00:47:32+00 ve32upmjz5dgdknpbleeca5tri | failed | Found duplicate key while validating index for UCVs | INDEX_BUILD | 1259 | 26396 | public.idx_users_email | 2025-05-20 00:49:49+00 | 2025-05-20 00:49:56+00 (2 rows)