Utilisation d'API pour créer un index
Vous pouvez créer un index pour une table NoSQL à l'aide de commandes SQL ou de l'API TableRequest
.
Rubriques connexes
Utilisation des commandes SQL
Un index peut être créé à l'aide de la commande CREATE INDEX
.
Créez un index de champ unique :
CREATE INDEX fixedschema_conf ON baggageInfo(confNo)
Vous trouverez ci-dessus un exemple d'index de schéma fixe à colonne unique. L'index est créé sur le champ confNo
avec le type de données string
dans la table baggageInfo
.
Créez un index composite :
CREATE INDEX compindex_namephone ON baggageInfo(fullName,contactPhone)
Remarques :
Un ou plusieurs champs de cet index peuvent être des colonnes de schéma fixe.Créez un index JSON :
Un index est appelé index JSON si au moins un des champs se trouve dans les données JSON. JSON étant sans schéma, le type de données d'un champ JSON indexé peut être différent d'une ligne à l'autre. Lors de la création d'un index sur des champs JSON, si vous ne savez pas quel type de données attendre pour le champ JSON, vous pouvez utiliser le type de données anyAtomic. Vous pouvez également indiquer l'un des types de données atomiques Oracle NoSQL Database. Pour ce faire, déclarez un type de données à l'aide du mot-clé AS en regard de chaque chemin d'index dans le champ JSON.
CREATE INDEX jsonindex_tagnum ON baggageInfo(bagInfo[].tagnum as INTEGER)
Ce qui précède est un exemple d'index JSON. L'index est créé sur le champ tagnum
présent dans le champ JSON baginfo
de la table baggageInfo
. Vous indiquez un type de données pour le champ tagnum
lors de la création de l'index.
La création d'un index JSON échouera si la table associée contient des lignes avec des données qui enfreignent le type de données déclaré. De même, après la création d'un index JSON, une opération d'insertion/mise à jour échoue si la nouvelle ligne n'est pas conforme au type de données déclaré dans l'index JSON.
CREATE INDEX jsonindex_routing ON baggageInfo(bagInfo[].routing as ANYATOMIC)
- Nombres
- Chaîne
- valeur booléenne
Cependant, cet avantage est compensé par les coûts d'espace et de CPU. En effet, les valeurs numériques de tout type dans le champ indexé seront converties en nombres avant d'être stockées dans l'index. Cette conversion prend du temps CPU et le stockage résultant pour le nombre sera plus grand que le stockage d'origine pour le nombre.
Créez un index simple :
Un index est appelé index simple si, pour chaque ligne de données de la table, une entrée est créée dans l'index. L'index renvoie une valeur unique de type données atomiques ou toute valeur spéciale (SQL NULL, JSON NULL, EMPTY). Essentiellement, les chemins d'index d'un index simple ne doivent pas renvoyer de tableau, de carte ou de type de données imbriqué.
CREATE INDEX simpleindex_arrival ON baggageInfo(bagInfo[].lastSeenTimeGmt as ANYATOMIC,
bagInfo[].bagArrivalDate as ANYATOMIC, bagInfo[].lastSeenTimeStation as ANYATOMIC)
Ce qui précède est un exemple d'index simple créé sur un document JSON dans un champ JSON. L'index est créé sur lastSeenTimeGmt
, bagArrivalDate
et lastSeenTimeStation
, tous à partir du document JSON bagInfo
dans le champ JSON d'informations de la table baggageInfo
. Si l'évaluation d'un chemin d'index simple renvoie un résultat vide, la valeur spéciale EMPTY est utilisée comme entrée d'index. Dans l'exemple ci-dessus, s'il n'existe aucune entrée lastSeenTimeGmt
, bagArrivalDate
ou lastSeenTimeStation
dans le document JSON bagInfo
, ou s'il n'existe aucun tableau JSON bagInfo
, la valeur spéciale EMPTY est indexée.
Créez un index à plusieurs clés :
Un index est appelé index à plusieurs clés si, pour chaque ligne de données de la table, plusieurs entrées sont créées dans l'index. Dans un index à plusieurs clés, au moins un chemin d'index utilise un tableau ou un type de données imbriqué. Dans un index à plusieurs clés, pour chaque ligne de table, des entrées d'index sont créées sur tous les éléments des tableaux en cours d'indexation.
CREATE INDEX multikeyindex1 ON stream_acct (acct_data.contentStreamed[].seriesInfo[] AS ANYATOMIC)
L'index est créé sur le tableau seriesInfo[]
dans la table stream_acct. Ici, tous les éléments du tableau seriesInfo[]
de chaque ligne de la table stream_acct
seront indexés.
Exemple 2 : index multiclé imbriqué : créez un index sur le tableau des détails d'épisode de l'application de compte de transmission en continu.
CREATE INDEX multikeyindex2 ON stream_acct (
acct_data.contentStreamed[].seriesInfo[].episodes[] AS ANYATOMIC)
Ce qui précède est un exemple d'index multiclé imbriqué où le champ est présent dans un tableau présent dans un autre tableau. L'index est créé sur le tableau episodes[]
dans le tableau seriesInfo[]
dans le JSON acct_data
de la table stream_acct
.
Exemple 3 : index multiclé composite :
CREATE INDEX multikeyindex3 ON stream_acct (acct_data.country AS ANYATOMIC,
acct_data.contentStreamed[].seriesInfo[].episodes[] AS ANYATOMIC)
Ce qui précède est un exemple d'index multi-clé composite ayant un chemin d'index multi-clé et un chemin d'index simple. L'index est créé sur le champ country
et le tableau episodes[]
dans la colonne JSON acct_data
de la table stream_acct
.
Reportez-vous à la section Specifications & Restrictions on Multikey index pour en savoir plus sur les restrictions relatives à l'index multi-clé.
Créer un index avec une clause NO NULLS
CREATE INDEX nonull_phone ON baggageInfo (contactPhone) WITH NO NULLS
- La requête ci-dessus crée un index sur le numéro de téléphone des passagers. Si certains passagers n'ont pas de numéro de téléphone, ces champs ne feront pas partie de l'index.
- Les index créés avec la clause WITH NO NULLS peuvent être utiles lorsque les données contiennent beaucoup de valeurs NULL et/ou EMPTY sur les champs indexés. Cela réduit le temps et l'espace pendant l'indexation.
- Toutefois, l'utilisation de ces index par les requêtes est limitée. Si un index est créé avec la clause WITH NO NULLS, les prédicats IS NULL et NOT EXISTS ne peuvent pas être utilisés comme prédicats d'index pour cet index.
- En fait, un tel index ne peut être utilisé par une requête que si celle-ci a un prédicat d'index pour chacun des champs indexés.
Créer un index avec des clés uniques par ligne
CREATE INDEX idx_showid ON
stream_acct(acct_data.contentStreamed[].showId AS INTEGER)
WITH UNIQUE KEYS PER ROW
Dans la requête ci-dessus, un index est créé sur showId
et il ne peut pas y avoir de showId
en double pour un seul tableau contentStreamed
. Cela informe le processeur de requête que, pour tout utilisateur de transmission en continu, le tableau contentStreamed
ne peut pas contenir plusieurs affichages avec le même ID d'affichage. La restriction est nécessaire car si des ID d'affichage en double existaient, ils ne seraient pas inclus dans l'index. Si vous insérez une ligne avec le même élément showId
dans un seul tableau contentStreamed
, une erreur est générée et l'opération d'insertion échoue.
Optimisation lors de l'exécution de la requête :
Lorsque vous créez un index avec des clés uniques par ligne, il contient moins d'entrées que le nombre d'éléments dans le tableau contentStreamed
. Vous pouvez écrire une requête efficace pour utiliser cet index. L'utilisation d'un tel index par l'interrogation produirait moins de résultats de la clause FROM que si l'index n'était pas utilisé.
Exemples de création d'index sur des fonctions :
BaggageInfo
en fonction de l'heure de modification la plus récente :CREATE INDEX idx_modtime ON BaggageInfo(modification_time())
modification_time
.SELECT * FROM BaggageInfo $u WHERE
modification_time($u) > "2019-08-01T10:45:00"
Cette requête renvoie toutes les lignes dont l'heure de modification la plus récente est postérieure à 2019-08-01T10 :45:00. Il utilise l'index idx_modtime
défini ci-dessus. Vous pouvez le vérifier en consultant le plan de requête à l'aide de la commande show query
.
BaggageInfo
sur la longueur du champ de routage.CREATE INDEX idx_routlen ON BaggageInfo (length(bagInfo[].routing as string))
length
.SELECT * from BaggageInfo $bag where length($bag.bagInfo[].routing) > 10
Cette requête renvoie toutes les lignes dont la longueur du champ de routage est supérieure à 10. Il utilise l'index idx_routlen
défini ci-dessus. Vous pouvez le vérifier en consultant le plan de requête à l'aide de la commande show query
.
Exemple 3 : utilisation d'un chemin d'index à plusieurs clés
stream_acct
en fonction de l'ID des émissions qu'ils regardent et de l'année et du mois des dates auxquelles l'émission a été regardée.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
. Vous pouvez le vérifier en consultant le plan de requête à l'aide de la commande show query
.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"
}
]
}
Utilisation de l'API TableRequest
Vous pouvez utiliser l'API TableRequest pour créer un index sur une table NoSQL.
La classe TableRequest
permet de créer un index sur une table. L'exécution des opérations spécifiées par cette demande est asynchrone. Il s'agit d'opérations potentiellement longues. TableResult
est renvoyé par les opérations TableRequest
et encapsule l'état de la table. Pour plus d'informations sur la classe TableRequest
et ses méthodes, reportez-vous à Référence d'API du kit SDK Java Oracle NoSQL.
/**
* 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");
}
La classe borneo.TableRequest
permet de créer un index sur une table. Tous les appels vers borneo.NoSQLHandle.table_request()
sont asynchrones. Il est donc nécessaire de vérifier le résultat et d'appeler borneo.TableResult.wait_for_completion()
pour attendre la fin de l'opération. Pour plus d'informations sur table_request
et ses méthodes, reportez-vous à Référence d'API du kit SDK Python Oracle NoSQL.
#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')
La classe TableRequest
permet de créer un index sur une table. L'exécution des opérations indiquées par TableRequest
est asynchrone. Il s'agit d'opérations potentiellement longues. Cette demande est utilisée en tant qu'entrée d'une opération Client.DoTableRequest()
, qui renvoie une valeur TableResult
pouvant être utilisée pour effectuer une interrogation jusqu'à ce que la table atteigne l'état souhaité. Pour plus d'informations sur les différentes méthodes de la classe TableRequest
, reportez-vous à Référence d'API du kit SDK Go Oracle NoSQL.
//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
}
Vous pouvez créer un index sur une table à l'aide de la méthode tableDDL
. Cette méthode est asynchrone et renvoie la promesse TableResult
. TableResult
est un objet JavaScript simple qui encapsule l'état de la table. Pour plus d'informations sur les méthodes, reportez-vous à la classe 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);
}
Pour créer un index sur une table, utilisez l'une des méthodes ExecuteTableDDLAsync
ou ExecuteTableDDLWithCompletionAsync
. Ces deux méthodes renvoient Task<TableResult>
. L'instance TableResult
contient le statut de l'opération LDD telle que TableState et le schéma de table. Pour plus d'informations sur ces méthodes, reportez-vous à Référence d'API du kit SDK Dotnet Oracle NoSQL.
// 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);
}