

Die vorliegende Übersetzung wurde maschinell erstellt. Im Falle eines Konflikts oder eines Widerspruchs zwischen dieser übersetzten Fassung und der englischen Fassung (einschließlich infolge von Verzögerungen bei der Übersetzung) ist die englische Fassung maßgeblich.

# Asynchrone Indizes in Aurora DSQL
<a name="working-with-create-index-async"></a>

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.  
 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
<a name="working-with-create-index-syntax"></a>

`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 ]
```

## Parameters
<a name="working-with-create-index-parameters"></a>

**`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 automatisch `table1_col1_col2_idx`.

**`NULLS FIRST | LAST`**  
Die Sortierreihenfolge von NULL- und Nicht-NULL-Spalten: `FIRST` gibt an, dass Aurora DSQL NULL-Spalten vor Nicht-NULL-Spalten sortieren soll. `LAST` bedeutet, 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 DISTINCT` hingegen gibt an, dass ein Index keine mehrfachen NULL-Werte in einer Spalte zulassen darf.

## Nutzungshinweise
<a name="working-with-create-index-usage-notes"></a>

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)'your_index_creation_job_id'`-Verfahren nützlich. Es stellt sicher, dass nachfolgende DDL- und DML-Operationen auf den neu erstellten Index abzielen.
+ 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 von `completed` oder länger als `failed` 30 Minuten haben. `sys.jobs` zeigt 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
<a name="working-with-create-index-example"></a>

Im folgenden Beispiel wird gezeigt, wie Sie ein Schema, eine Tabelle und dann einen Index erstellen.

1. 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));
   ```

1. Fügen Sie eine Zeile in die Tabelle ein.

   ```
   INSERT INTO test.departments VALUES ('Human Resources', 'John Doe', '10')
   ```

1. Erstellen Sie einen asynchronen Index.

   ```
   CREATE INDEX ASYNC test_index on test.departments(name, manager, size);
   ```

   Der Befehl `CREATE INDEX` gibt eine Auftrags-ID zurück, wie im Folgenden dargestellt.

   ```
   job_id 
   -------------------------- 
   jh2gbtx4mzhgfkbimtgwn5j45y
   ```

   `job_id` zeigt an, dass Aurora DSQL einen neuen Auftrag zur Indexerstellung eingereicht hat. Sie können das Verfahren `sys.wait_for_job(job_id)'your_index_creation_job_id'` verwenden, um andere Arbeiten an der Sitzung zu blockieren, bis der Auftrag abgeschlossen ist oder ein Timeout eintritt.

## Abfragen des Indexerstellungsstatus: Beispiel
<a name="dsql-index-status-example"></a>

Fragen Sie die Systemansicht `sys.jobs` ab, um den Erstellungsstatus Ihres Index zu überprüfen, wie im folgenden Beispiel gezeigt:

```
SELECT * FROM sys.jobs where job_id = 'wqhu6ewifze5xitg3umt24h5ua';
```

Aurora DSQL gibt eine Antwort zurück, die in etwa wie folgt aussieht:

```
           job_id           |  status   | details |  job_type   | class_id | object_id |    object_name    |       start_time       |      update_time
----------------------------+-----------+---------+-------------+----------+-----------+-------------------+------------------------+------------------------
 wqhu6ewifze5xitg3umt24h5ua | completed |         | INDEX_BUILD |     1259 |     26433 | public.nt2_c1_idx | 2025-09-25 22:07:31+00 | 2025-09-25 22:07:46+00
```

Die Statusspalte kann einen der folgenden Werte enthalten:


| Status | Description | 
| --- | --- | 
| submitted | Die Aufgabe wurde eingereicht, aber Aurora DSQL hat noch nicht mit der Verarbeitung begonnen. | 
| processing | Aurora DSQL verarbeitet die Aufgabe. | 
| failed | 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. | 
| completed | Aurora DSQL hat die Aufgabe erfolgreich abgeschlossen. | 

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
<a name="unique-index-failures"></a>

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**

1. 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.

1. Löschen Sie den fehlgeschlagenen Index.

1. Geben Sie einen neuen Befehl zum Erstellen eines Index ein.

## So erkennen Sie Eindeutigkeitsverstöße in Primärtabellen
<a name="detect-uniqueness-violation"></a>

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)
```