Optimisation des jointures d’asymétrie à l’aide d’indicateurs d’asymétrie
Important
Cette documentation a été mise hors service et peut ne pas être mise à jour. Les produits, services ou technologies mentionnés dans ce contenu ne sont plus pris en charge.
Les indications de jointure asymétrique ne sont pas requises. Databricks gère l’asymétrie par défaut à l’aide de l’exécution de requête adaptative (AQE, Adaptive Query Execution). Voir Exécution de requête adaptative.
Remarque
spark.sql.adaptive.skewJoin.enabled
doit être True
, qui est le paramètre par défaut dans Azure Databricks.
Qu’est-ce que l'asymétrie des données ?
L’asymétrie des données est une condition dans laquelle les données d’une table sont distribuées de manière inégale entre les partitions du cluster. L’asymétrie des données peut réduire considérablement les performances des requêtes, en particulier celles qui comportent des jointures. Les jointures entre de grandes tables nécessitent la lecture aléatoire des données, et l’asymétrie peut entraîner un déséquilibre extrême du travail dans le cluster. Il est probable que l’asymétrie des données concerne une requête si celle-ci semble bloquée à la fin de très peu de tâches (par exemple, les 3 dernières tâches sur 200). Pour vérifier que l’asymétrie des données affecte une requête :
- Cliquez sur l’étape qui est bloquée et vérifiez qu’elle effectue une jointure.
- Une fois la requête terminée, recherchez l’étape qui effectue une jointure et vérifiez la distribution de la durée des tâches.
- Triez les tâches par durée décroissante et vérifiez les premières tâches. Si une tâche a pris beaucoup plus de temps que les autres, il y a une asymétrie.
Pour améliorer l’asymétrie, Delta Lake sur Azure Databricks SQL accepte les conseils d’asymétrie dans les requêtes. Grâce aux informations fournies par un conseil d’asymétrie, Databricks Runtime peut élaborer un meilleur plan de requête, qui ne souffre pas de l’asymétrie des données.
Configurer le conseil d’asymétrie avec le nom de la relation
Un conseil d’asymétrie doit contenir au moins le nom de la relation avec asymétrie. Une relation est une table, une vue ou une sous-requête. Toutes les jointures associées à cette relation utilisent alors l’optimisation des jointures asymétriques.
-- table with skew
SELECT /*+ SKEW('orders') */
*
FROM orders, customers
WHERE c_custId = o_custId
-- subquery with skew
SELECT /*+ SKEW('C1') */
*
FROM (SELECT * FROM customers WHERE c_custId < 100) C1, orders
WHERE C1.c_custId = o_custId
Configurer le conseil d’asymétrie avec le nom de la relation et les noms des colonnes
Il peut y avoir plusieurs jointures sur une relation, et seules certaines d’entre elles souffriront d’asymétrie. L’optimisation des jointures asymétriques a une certaine surcharge, il est donc préférable de l’utiliser uniquement lorsque cela est nécessaire. À cet effet, le conseil d’asymétrie accepte les noms de colonnes. Seules les jointures avec ces colonnes utilisent l’optimisation des jointures asymétriques.
-- single column
SELECT /*+ SKEW('orders', 'o_custId') */
*
FROM orders, customers
WHERE o_custId = c_custId
-- multiple columns
SELECT /*+ SKEW('orders', ('o_custId', 'o_storeRegionId')) */
*
FROM orders, customers
WHERE o_custId = c_custId AND o_storeRegionId = c_regionId
Configurer le conseil d’asymétrie avec le nom de la relation, les noms des colonnes et les valeurs d’asymétrie
Vous pouvez également spécifier des valeurs d’asymétrie dans le conseil. Selon la requête et les données, les valeurs d’asymétrie peuvent être connues (par exemple, parce qu’elles ne changent jamais) ou faciles à trouver. Cela permet de réduire la surcharge de l’optimisation des jointures asymétriques. Sinon, Delta Lake les détecte automatiquement.
-- single column, single skew value
SELECT /*+ SKEW('orders', 'o_custId', 0) */
*
FROM orders, customers
WHERE o_custId = c_custId
-- single column, multiple skew values
SELECT /*+ SKEW('orders', 'o_custId', (0, 1, 2)) */
*
FROM orders, customers
WHERE o_custId = c_custId
-- multiple columns, multiple skew values
SELECT /*+ SKEW('orders', ('o_custId', 'o_storeRegionId'), ((0, 1001), (1, 1002))) */
*
FROM orders, customers
WHERE o_custId = c_custId AND o_storeRegionId = c_regionId