Indizes mit APIs erstellen
Sie können einen Index für eine NoSQL-Tabelle mit SQL-Befehlen oder mit der TableRequest
-API erstellen.
Verwandte Themen
SQL-Befehle verwenden
Mit dem Befehl CREATE INDEX
kann ein Index erstellt werden.
Einzelfeldindex erstellen:
CREATE INDEX fixedschema_conf ON baggageInfo(confNo)
Das obige Beispiel zeigt einen einspaltigen festen Schemaindex. Der Index wird für das Feld confNo
mit dem Datentyp string
in der Tabelle baggageInfo
erstellt.
Erstellen Sie einen zusammengesetzten Index:
CREATE INDEX compindex_namephone ON baggageInfo(fullName,contactPhone)
Hinweis:
Sie können ein oder mehrere Felder dieses Index als feste Schemaspalten verwenden.Erstellen Sie einen JSON-Index:
Ein Index wird als JSON-Index bezeichnet, wenn sich mindestens eines der Felder in JSON-Daten befindet. Da JSON keine Schemas enthält, kann sich der Datentyp eines indizierten JSON-Feldes zeilenübergreifend unterscheiden. Wenn Sie beim Erstellen eines Index für JSON-Felder nicht sicher sind, welcher Datentyp für das JSON-Feld zu erwarten ist, können Sie den Datentyp anyAtomic verwenden. Alternativ können Sie einen der atomaren Datentypen von Oracle NoSQL Database angeben. Dazu deklarieren Sie einen Datentyp mit dem AS-Schlüsselwort neben jedem Indexpfad im JSON-Feld.
CREATE INDEX jsonindex_tagnum ON baggageInfo(bagInfo[].tagnum as INTEGER)
Das obige Beispiel ist ein JSON-Index. Der Index wird für das Feld tagnum
erstellt, das im JSON-Feld baginfo
in der Tabelle baggageInfo
vorhanden ist. Beachten Sie, dass Sie beim Erstellen des Index einen Datentyp für das Feld tagnum
angeben.
Die Erstellung eines JSON-Index verläuft nicht erfolgreich, wenn die verknüpfte Tabelle Zeilen mit Daten enthält, die den deklarierten Datentyp verletzen. Entsprechend verläuft ein Einfüge-/Aktualisierungsvorgang nach dem Erstellen eines JSON-Index nicht erfolgreich, wenn die neue Zeile nicht dem deklarierten Datentyp im JSON-Index entspricht.
CREATE INDEX jsonindex_routing ON baggageInfo(bagInfo[].routing as ANYATOMIC)
- Zahlen
- String (Zeichenfolgendatentyp)
- boolean (boolescher Datentyp)
Dieser Vorteil wird jedoch durch Platz- und CPU-Kosten kompensiert. Dies liegt daran, dass numerische Werte jeder Art im indizierten Feld in die Zahl konvertiert werden, bevor sie im Index gespeichert werden. Dieser Cast benötigt CPU-Zeit, und der resultierende Speicher für die Anzahl ist größer als der ursprüngliche Speicher für die Anzahl.
Erstellen Sie einen einfachen Index:
Ein Index wird als einfacher Index bezeichnet, wenn für jede Datenzeile in der Tabelle ein Eintrag im Index erstellt wird. Der Index gibt einen einzelnen Wert vom atomaren Datentyp oder einem beliebigen Sonderwert zurück (SQL NULL, JSON NULL, EMPTY). Im Wesentlichen dürfen die Indexpfade eines einfachen Index kein Array oder Map oder einen verschachtelten Datentyp zurückgeben.
CREATE INDEX simpleindex_arrival ON baggageInfo(bagInfo[].lastSeenTimeGmt as ANYATOMIC,
bagInfo[].bagArrivalDate as ANYATOMIC, bagInfo[].lastSeenTimeStation as ANYATOMIC)
Das obige Beispiel ist ein einfacher Index, der für ein JSON-Dokument in einem JSON-Feld erstellt wurde. Der Index wird für lastSeenTimeGmt
, bagArrivalDate
und lastSeenTimeStation
erstellt, alle aus dem JSON-Dokument bagInfo
im JSON-Infofeld in der Tabelle baggageInfo
. Wenn die Auswertung eines einfachen Indexpfads ein leeres Ergebnis zurückgibt, wird der Sonderwert EMPTY als Indexeintrag verwendet. Im obigen Beispiel wird der Sonderwert EMPTY indexiert, wenn im JSON-Dokument bagInfo
kein Eintrag lastSeenTimeGmt
, bagArrivalDate
oder lastSeenTimeStation
vorhanden ist oder kein JSON-Array bagInfo
vorhanden ist.
Erstellen Sie einen Multikey-Index:
Ein Index wird als Mehrfachindex bezeichnet, wenn für jede Datenzeile in der Tabelle mehrere Einträge im Index erstellt werden. In einem Mehrzweckindex gibt es mindestens einen Indexpfad, der ein Array oder einen verschachtelten Datentyp verwendet. In einem Mehrfachindex werden für jede Tabellenzeile Indexeinträge für alle Elemente in Arrays erstellt, die indiziert werden.
CREATE INDEX multikeyindex1 ON stream_acct (acct_data.contentStreamed[].seriesInfo[] AS ANYATOMIC)
Der Index wird für das Array seriesInfo[]
in der Tabelle stream_acct erstellt. Hier werden alle Elemente im Array seriesInfo[]
in jeder Zeile der Tabelle stream_acct
indexiert.
Beispiel 2: Verschachtelter Index mit mehreren Episoden: Erstellen Sie einen Index für das Episodendetailarray der Streamingaccountanwendung.
CREATE INDEX multikeyindex2 ON stream_acct (
acct_data.contentStreamed[].seriesInfo[].episodes[] AS ANYATOMIC)
Das obige Beispiel ist ein verschachtelter Mehrfachindex, bei dem das Feld in einem Array vorhanden ist, das in einem anderen Array vorhanden ist. Der Index wird für das Array episodes[]
im Array seriesInfo[]
in der JSON-Datei acct_data
der Tabelle stream_acct
erstellt.
Beispiel 3: Zusammengesetzter mehrstufiger Index:
CREATE INDEX multikeyindex3 ON stream_acct (acct_data.country AS ANYATOMIC,
acct_data.contentStreamed[].seriesInfo[].episodes[] AS ANYATOMIC)
Das obige Beispiel ist ein zusammengesetzter mehrgleicher Index mit einem mehrgleisen Indexpfad und einem einfachen Indexpfad. Der Index wird für das Feld country
und das Array episodes[]
in der JSON-Spalte acct_data
der Tabelle stream_acct
erstellt.
Weitere Informationen zu Einschränkungen für Multikey-Indizes finden Sie unter Spezifikationen und Einschränkungen für Multikey-Indizes.
Index mit NO NULLS-Klausel erstellen
CREATE INDEX nonull_phone ON baggageInfo (contactPhone) WITH NO NULLS
- Die obige Abfrage erstellt einen Index für die Telefonnummer der Passagiere. Wenn einige Passagiere keine Telefonnummer haben, sind diese Felder nicht Teil des Index.
- Die Indizes, die mit der WITH NO NULLS-Klausel erstellt werden, können nützlich sein, wenn die Daten viele NULL- und/oder EMPTY-Werte für die indizierten Felder enthalten. Dadurch wird der Zeit- und Speicherplatzaufwand während der Indexierung reduziert.
- Die Verwendung solcher Indizes durch Abfragen ist jedoch eingeschränkt. Wenn ein Index mit der Klausel WITH NO NULLS erstellt wird, können die Prädikate IS NULL und NOT EXISTS nicht als Indexprädikate für diesen Index verwendet werden.
- Tatsächlich kann ein solcher Index von einer Abfrage nur verwendet werden, wenn die Abfrage ein Indexprädikat für jedes der indizierten Felder aufweist.
Index mit eindeutigen Schlüsseln pro Zeile erstellen
CREATE INDEX idx_showid ON
stream_acct(acct_data.contentStreamed[].showId AS INTEGER)
WITH UNIQUE KEYS PER ROW
In der obigen Abfrage wird ein Index für showId
erstellt, und showId
kann nicht für ein einzelnes contentStreamed
-Array dupliziert werden. Dadurch wird der Abfrageprozessor darüber informiert, dass das Array contentStreamed
für jeden Streamingbenutzer nicht mindestens zwei Shows mit derselben Show-ID enthalten darf. Die Einschränkung ist erforderlich, da doppelte Anzeigekennungen nicht im Index enthalten wären. Wenn Sie eine Zeile mit demselben showId
-Element mindestens zwei in ein einzelnes contentStreamed
-Array einfügen, wird ein Fehler ausgelöst, und der Einfügevorgang ist nicht erfolgreich.
Optimierung in der Abfragelaufzeit:
Wenn Sie einen Index mit eindeutigen Schlüsseln pro Zeile erstellen, enthält der Index weniger Einträge als die Anzahl der Elemente im Array contentStreamed
. Sie können eine effiziente Abfrage erstellen, um diesen Index zu verwenden. Die Verwendung eines solchen Index durch die Abfrage würde weniger Ergebnisse aus der FROM-Klausel ergeben, als wenn der Index nicht verwendet würde.
Beispiele für das Erstellen von Indizes für Funktionen:
BaggageInfo
nach ihrer letzten Änderungszeit indexiert:CREATE INDEX idx_modtime ON BaggageInfo(modification_time())
modification_time
als Filterbedingung enthält.SELECT * FROM BaggageInfo $u WHERE
modification_time($u) > "2019-08-01T10:45:00"
Diese Abfrage gibt alle Zeilen zurück, deren letzte Änderungszeit nach 2019-08-01T10:45:00 liegt. Er verwendet den oben definierten idx_modtime
-Index. Sie können dies prüfen, indem Sie den Abfrageplan mit dem Befehl show query
anzeigen.
BaggageInfo
auf die Länge des Routingfeldes indiziert.CREATE INDEX idx_routlen ON BaggageInfo (length(bagInfo[].routing as string))
length
als Filterbedingung enthält.SELECT * from BaggageInfo $bag where length($bag.bagInfo[].routing) > 10
Diese Abfrage gibt alle Zeilen zurück, deren Länge des Routingfeldes größer als 10 ist. Er verwendet den oben definierten idx_routlen
-Index. Sie können dies prüfen, indem Sie den Abfrageplan mit dem Befehl show query
anzeigen.
Beispiel 3: Verwenden eines Indexpfads mit mehreren Schlüsseln
stream_acct
nach der ID der Shows, die sie ansehen, sowie Jahr und Monat der Datumsangaben, an denen die Show angesehen wurde.CREATE INDEX idx_showid_year_month ON
stream_acct(acct_data.contentStreamed[].showId AS INTEGER,
substring(acct_data.contentStreamed[].seriesInfo[].episodes[].date AS STRING,0, 4),
substring(acct_data.contentStreamed[].seriesInfo[].episodes[].date AS STRING,5, 2))
SELECT count(*) FROM stream_acct s1 WHERE EXISTS
s1.acct_data.contentStreamed[$element.showId = 16].seriesInfo.
episodes[substring($element.date, 0, 4) = "2022"]
idx_showid_year_month
. Sie können dies prüfen, indem Sie den Abfrageplan mit dem Befehl show query
anzeigen.show query SELECT count(*) FROM stream_acct s1 WHERE EXISTS
> s1.acct_data.contentStreamed[$element.showId = 16].seriesInfo.episodes[substring($element.date, 0, 4) = "2022"]
{
"iterator kind" : "GROUP",
"input variable" : "$gb-1",
"input iterator" :
{
"iterator kind" : "RECEIVE",
"distribution kind" : "ALL_SHARDS",
"distinct by fields at positions" : [ 1 ],
"input iterator" :
{
"iterator kind" : "SELECT",
"FROM" :
{
"iterator kind" : "TABLE",
"target table" : "stream_acct",
"row variable" : "$$s1",
"index used" : "idx_showid_year_month",
"covering index" : true,
"index row variable" : "$$s1_idx",
"index scans" : [
{
"equality conditions" : {"acct_data.contentStreamed[].showId":16,"substring#acct_data.contentStreamed[].seriesInfo[].episodes[].date@,0,4":"2022"},
"range conditions" : {}
}
]
},
"FROM variable" : "$$s1_idx",
"SELECT expressions" : [
{
"field name" : "Column_1",
"field expression" :
{
"iterator kind" : "CONST",
"value" : 1
}
},
{
"field name" : "acct_id_gen",
"field expression" :
{
"iterator kind" : "FIELD_STEP",
"field name" : "#acct_id",
"input iterator" :
{
"iterator kind" : "VAR_REF",
"variable" : "$$s1_idx"
}
}
}
]
}
},
"grouping expressions" : [
],
"aggregate functions" : [
{
"iterator kind" : "FUNC_COUNT_STAR"
}
]
}
API TableRequest verwenden
Mit der TableRequest-API können Sie einen Index für eine NoSQL-Tabelle erstellen.
Mit der Klasse TableRequest
wird ein Index für eine Tabelle erstellt. Die Ausführung der von dieser Anforderung angegebenen Vorgänge ist asynchron. Dies sind möglicherweise Operationen mit langer Ausführungszeit. TableResult
wird von TableRequest
-Vorgängen zurückgegeben und kapselt den Status der Tabelle. Weitere Informationen zur Klasse TableRequest
und ihren Methoden finden Sie unter Oracle NoSQL Java-SDK-API-Referenz.
/**
* Create an index acct_episodes in the stream_acct table
*/
private static void crtIndex(NoSQLHandle handle) throws Exception {
String createIndexDDL = "CREATE INDEX acct_episodes ON " + tableName +
"(acct_data.contentStreamed[].seriesInfo[].episodes[] AS ANYATOMIC)";
TableRequest treq = new TableRequest().setStatement(createIndexDDL);
TableResult tres = handle.tableRequest(treq);
tres.waitForCompletion(handle, 60000, /* wait 60 sec */
1000); /* delay ms for poll */
System.out.println("Index acct_episodes on " + tableName + " is created");
}
Mit der Klasse borneo.TableRequest
wird ein Index für eine Tabelle erstellt. Alle Aufrufe von borneo.NoSQLHandle.table_request()
sind asynchron. Daher müssen Sie das Ergebnis prüfen und borneo.TableResult.wait_for_completion()
aufrufen, um auf den Abschluss des Vorgangs zu warten. Weitere Informationen zu table_request
und den zugehörigen Methoden finden Sie unter Oracle NoSQL Python-SDK-API-Referenz.
#create an index
def create_index(handle):
statement = '''CREATE INDEX acct_episodes ON stream_acct (acct_data.contentStreamed[].seriesInfo[].episodes[] AS ANYATOMIC)'''
request = TableRequest().set_statement(statement)
table_result = handle.do_table_request(request, 40000, 3000)
table_result.wait_for_completion(handle, 40000, 3000)
print('Index acct_episodes on the table stream_acct is created')
Mit der Klasse TableRequest
wird ein Index für eine Tabelle erstellt. Die Ausführung von Vorgängen, die mit TableRequest
angegeben werden, ist asynchron. Dies sind möglicherweise Operationen mit langer Ausführungszeit. Diese Anforderung wird als Eingabe eines Client.DoTableRequest()
-Vorgangs verwendet, der eine TableResult
zurückgibt, die zum Polling verwendet werden kann, bis die Tabelle den gewünschten Status erreicht. Weitere Informationen zu den verschiedenen Methoden der Klasse TableRequest
finden Sie in der Oracle NoSQL Go-SDK-API-Referenz.
//create an index on a table
func createIndex(client *nosqldb.Client, err error, tableName string)(){
stmt := fmt.Sprintf("CREATE INDEX acct_episodes ON %s "+
"(acct_data.contentStreamed[].seriesInfo[].episodes[] AS ANYATOMIC)",tableName)
tableReq := &nosqldb.TableRequest{
Statement: stmt,
}
tableRes, err := client.DoTableRequest(tableReq)
if err != nil {
fmt.Printf("cannot initiate CREATE INDEX request: %v\n", err)
return
}
// The create index request is asynchronous, wait for index creation to complete.
_, err = tableRes.WaitForCompletion(client, 60*time.Second, time.Second)
if err != nil {
fmt.Printf("Error finishing CREATE INDEX request: %v\n", err)
return
}
fmt.Println("Created Index acct_episodes on table ", tableName)
return
}
Sie können einen Index für eine Tabelle mit der Methode tableDDL
erstellen. Diese Methode ist asynchron und gibt eine Zusage von TableResult
zurück. TableResult
ist ein einfaches JavaScript-Objekt, das den Status der Tabelle kapselt. Details zur Methode finden Sie in der Klasse NoSQLClient.
//creates an index
async function createIndex(handle) {
const crtindDDL = `CREATE INDEX acct_episodes ON ${TABLE_NAME}(acct_data.contentStreamed[].seriesInfo[].episodes[] AS ANYATOMIC)`;
let res = await handle.tableDDL(crtindDDL);
console.log('Index acct_episodes is created on table:' + TABLE_NAME);
}
Um einen Index für eine Tabelle zu erstellen, verwenden Sie eine der Methoden ExecuteTableDDLAsync
oder ExecuteTableDDLWithCompletionAsync
. Beide Methoden geben Task<TableResult>
zurück. Die TableResult
-Instanz enthält den Status des DDL-Vorgangs, wie TableState und das Tabellenschema. Weitere Informationen zu diesen Methoden finden Sie in der Oracle NoSQL Dotnet-SDK-API-Referenz.
// Creates an index on a table
private static async Task createIndex(NoSQLClient client){
var sql =
$@"CREATE INDEX acct_episodes ON {TableName}(acct_data.contentStreamed[].seriesInfo[].episodes[] AS ANYATOMIC)";
var tableResult = await client.ExecuteTableDDLAsync(sql);
// Wait for the operation completion
await tableResult.WaitForCompletionAsync();
Console.WriteLine(" Index acct_episodes is created on table Table {0}",
tableResult.TableName);
}