

Les traductions sont fournies par des outils de traduction automatique. En cas de conflit entre le contenu d'une traduction et celui de la version originale en anglais, la version anglaise prévaudra.

# Optimisez les requêtes CloudTrail Lake
<a name="lake-queries-optimization"></a>

Cette page fournit des conseils sur la manière d'optimiser les requêtes CloudTrail Lake afin d'améliorer les performances et la fiabilité. Il couvre des techniques d'optimisation spécifiques ainsi que des solutions de contournement pour les échecs de requêtes courants.

**Topics**
+ [Recommandations pour optimiser les requêtes](#lake-queries-tuning)
+ [Solutions en cas d'échec des requêtes](#lake-queries-troubleshooting)

## Recommandations pour optimiser les requêtes
<a name="lake-queries-tuning"></a>

Suivez les recommandations de cette section pour optimiser vos requêtes.

**Topics**
+ [Optimisation des agrégations](#query-optimization-aggregation)
+ [Utiliser des techniques d'approximation](#query-optimization-approximation)
+ [Limiter les résultats des requêtes](#query-optimization-limit)
+ [Optimisez les requêtes LIKE](#query-optimization-like)
+ [Utilisez `UNION ALL` au lieu de `UNION`](#query-optimization-union)
+ [Inclure uniquement les colonnes obligatoires](#query-optimization-reqcolumns)
+ [Réduire la portée des fonctions de la fenêtre](#query-optimization-windows)

### Optimisation des agrégations
<a name="query-optimization-aggregation"></a>

L'exclusion des colonnes redondantes dans les `GROUP BY` clauses peut améliorer les performances, car un nombre réduit de colonnes nécessite moins de mémoire. Par exemple, dans la requête suivante, nous pouvons utiliser la `arbitrary` fonction sur une colonne redondante `eventType` pour améliorer les performances. La `arbitrary` fonction on `eventType` est utilisée pour sélectionner la valeur du champ de manière aléatoire dans le groupe car la valeur est la même et n'a pas besoin d'être incluse dans la `GROUP BY` clause.

```
SELECT eventName, eventSource, arbitrary(eventType), count(*) 
FROM $EDS_ID 
GROUP BY eventName, eventSource
```

Il est possible d'améliorer les performances de la `GROUP BY` fonction en ordonnant la liste des champs par ordre décroissant de leur nombre de valeurs uniques (cardinalité). `GROUP BY` Par exemple, lors de l'obtention du nombre d'événements d'un type dans chacun Région AWS, les performances peuvent être améliorées en utilisant l'`eventName``awsRegion`ordre dans la `GROUP BY` fonction au lieu de`awsRegion`, `eventName` car il y a `eventName` plus de valeurs uniques de que de`awsRegion`.

```
SELECT eventName, awsRegion, count(*) 
FROM $EDS_ID 
GROUP BY eventName, awsRegion
```

### Utiliser des techniques d'approximation
<a name="query-optimization-approximation"></a>

Lorsque des valeurs exactes ne sont pas nécessaires pour compter des valeurs distinctes, utilisez des [fonctions d'agrégation approximatives](https://trino.io/docs/current/functions/aggregate.html#approximate-aggregate-functions) pour trouver les valeurs les plus fréquentes. Par exemple, [https://trino.io/docs/current/functions/aggregate.html#approx_distinct](https://trino.io/docs/current/functions/aggregate.html#approx_distinct)utilise beaucoup moins de mémoire et s'exécute plus rapidement que l'`COUNT(DISTINCT fieldName)`opération.

### Limiter les résultats des requêtes
<a name="query-optimization-limit"></a>

Si seul un exemple de réponse est nécessaire pour une requête, limitez les résultats à un petit nombre de lignes en utilisant la `LIMIT` condition. Dans le cas contraire, la requête renverra des résultats volumineux et son exécution prendra plus de temps.

L'utilisation `LIMIT` avec `ORDER BY` permet d'obtenir des résultats plus rapidement pour les N premiers ou derniers enregistrements, car elle réduit la quantité de mémoire nécessaire et le temps nécessaire au tri.

```
SELECT * FROM $EDS_ID
ORDER BY eventTime 
LIMIT 100;
```

### Optimisez les requêtes LIKE
<a name="query-optimization-like"></a>

Vous pouvez utiliser `LIKE` pour trouver des chaînes correspondantes, mais avec de longues chaînes, cela demande beaucoup de calcul. La [https://trino.io/docs/current/functions/regexp.html#regexp_like](https://trino.io/docs/current/functions/regexp.html#regexp_like)fonction est dans la plupart des cas une alternative plus rapide.

Souvent, vous pouvez optimiser une recherche en ancrant la sous-chaîne que vous recherchez. Par exemple, si vous recherchez un préfixe, il est préférable d'utiliser « % » au lieu de « % `substr` % `substr` » avec l'`LIKE`opérateur et « ^ `substr` » avec la fonction. `regexp_like`

### Utilisez `UNION ALL` au lieu de `UNION`
<a name="query-optimization-union"></a>

`UNION ALL`et `UNION` sont deux manières de combiner les résultats de deux requêtes en un seul résultat tout en supprimant `UNION` les doublons. `UNION`doit traiter tous les enregistrements et trouver les doublons, ce qui demande beaucoup de mémoire et de calcul, mais `UNION ALL` c'est une opération relativement rapide. À moins que vous n'ayez besoin de dédupliquer des enregistrements, utilisez `UNION ALL` pour de meilleures performances.

### Inclure uniquement les colonnes obligatoires
<a name="query-optimization-reqcolumns"></a>

Si vous n'avez pas besoin d'une colonne, ne l'incluez pas dans votre requête. Moins une requête doit traiter de données, plus elle sera exécutée rapidement. Si vous avez des requêtes correspondant `SELECT *` à la requête la plus externe, vous devez les `*` remplacer par une liste de colonnes dont vous avez besoin.

La clause `ORDER BY` renvoie les résultats d'une requête dans un ordre trié. Lors du tri d'une plus grande quantité de données, si la mémoire requise n'est pas disponible, les résultats triés intermédiaires sont écrits sur le disque, ce qui peut ralentir l'exécution de la requête. Si vous n'avez pas strictement besoin que votre résultat soit trié, évitez d'ajouter une clause `ORDER BY`. Évitez également d'`ORDER BY`ajouter des requêtes internes si cela n'est pas strictement nécessaire. 

### Réduire la portée des fonctions de la fenêtre
<a name="query-optimization-windows"></a>

[Les fonctions de fenêtre](https://trino.io/docs/current/functions/window.html) conservent en mémoire tous les enregistrements sur lesquels elles opèrent afin de calculer leur résultat. Lorsque la fenêtre est très grande, la fonction de fenêtrage peut manquer de mémoire. Pour vous assurer que les requêtes s'exécutent dans les limites de mémoire disponible, réduisez la taille des fenêtres sur lesquelles vos fonctions de fenêtre opèrent en ajoutant une `PARTITION BY` clause.

Parfois, les requêtes comportant des fonctions de fenêtrage peuvent être réécrites sans fonctions de fenêtrage. Par exemple, au lieu d'utiliser `row_number` ou`rank`, vous pouvez utiliser des fonctions d'agrégation telles que [https://trino.io/docs/current/functions/aggregate.html#max_by](https://trino.io/docs/current/functions/aggregate.html#max_by)ou [https://trino.io/docs/current/functions/aggregate.html#min_by](https://trino.io/docs/current/functions/aggregate.html#min_by).

La requête suivante trouve le dernier alias attribué à chaque clé KMS à l'aide de`max_by`.

```
SELECT element_at(requestParameters, 'targetKeyId') as keyId, 
max_by(element_at(requestParameters, 'aliasName'), eventTime) as mostRecentAlias 
FROM $EDS_ID 
WHERE eventsource = 'kms.amazonaws.com' 
AND eventName in ('CreateAlias', 'UpdateAlias') 
AND eventTime > DATE_ADD('week', -1, CURRENT_TIMESTAMP) 
GROUP BY element_at(requestParameters, 'targetKeyId')
```

Dans ce cas, la `max_by` fonction renvoie l'alias de l'enregistrement indiquant l'heure du dernier événement au sein du groupe. Cette requête s'exécute plus rapidement et utilise moins de mémoire qu'une requête équivalente dotée d'une fonction de fenêtrage.

## Solutions en cas d'échec des requêtes
<a name="lake-queries-troubleshooting"></a>

Cette section propose des solutions aux échecs de requête courants.

**Topics**
+ [La requête échoue car la réponse est trop volumineuse](#large-responses)
+ [La requête échoue en raison de l'épuisement des ressources](#exhausted-resources)

### La requête échoue car la réponse est trop volumineuse
<a name="large-responses"></a>

Une requête peut échouer si la réponse est trop volumineuse, ce qui entraîne le message`Query response is too large`. Dans ce cas, vous pouvez réduire la portée de l'agrégation.

Les fonctions d'agrégation telles que celles-ci `array_agg` peuvent entraîner la très grande taille d'au moins une ligne de la réponse à la requête, ce qui entraîne l'échec de la requête. Par exemple, l'utilisation `array_agg(eventName)` au lieu de `array_agg(DISTINCT eventName)` augmentera considérablement la taille de la réponse en raison des noms d'événements dupliqués à partir des CloudTrail événements sélectionnés.

### La requête échoue en raison de l'épuisement des ressources
<a name="exhausted-resources"></a>

Si suffisamment de mémoire n'est pas disponible pendant l'exécution d'opérations gourmandes en mémoire telles que les jointures, les agrégations et les fonctions de fenêtre, les résultats intermédiaires sont répandus sur le disque, mais le déversement ralentit l'exécution des requêtes et peut être insuffisant pour empêcher l'échec de la requête. `Query exhausted resources at this scale factor` Cela peut être résolu en réessayant la requête.

Si les erreurs ci-dessus persistent même après l'optimisation de la requête, vous pouvez affiner la requête à l'aide `eventTime` des événements et exécuter la requête plusieurs fois à des intervalles plus courts par rapport à la plage de temps de la requête d'origine.