重要
このドキュメントは廃止され、更新されない可能性があります。 このコンテンツに記載されている製品、サービス、またはテクノロジはサポートされなくなりました。
スキュー結合ヒントは不要です。 Databricks は、アダプティブ クエリ実行 (AQE) を使用して、既定でスキューを処理します。 アダプティブ クエリ実行
手記
spark.sql.adaptive.skewJoin.enabled
True
する必要があります。これは、Azure Databricks の既定の設定です。
データ スキューとは
データスキューは、テーブルのデータがクラスター内のパーティション間で不均一に分散される状態です。 データ スキューにより、クエリのパフォーマンス (特に結合があるクエリ) が大幅にダウングレードされる可能性があります。 大規模なテーブル間の結合にはデータのシャッフルが必要であり、スキューによってクラスター内の作業の負荷が極端に不均衡になる可能性があります。 クエリが非常に少数のタスク (たとえば、200 個中の最後の 3 つのタスク) を終了して停止しているように見える場合、データ スキューがクエリに影響を与える可能性があります。 データ スキューがクエリに影響していることを確認するには:
- スタックしているステージをクリックし、結合を実行していることを確認します。
- クエリが完了したら、結合を実行するステージを見つけて、タスク期間の分布を確認します。
- 期間を減らすことでタスクを並べ替え、最初のいくつかのタスクを確認します。 1 つのタスクの完了に他のタスクよりも長い時間がかかる場合は、傾斜があります。
スキューを改善するために、Delta Lake on Azure Databricks SQL はクエリで スキュー ヒント を受け入れます。 スキュー ヒントからの情報を使用して、Databricks Runtime は、データ スキューを受けないように、より優れたクエリ プランを構築できます。
リレーション名を用いてスキューのヒントを設定する
スキュー ヒントには、少なくともスキューとの関係を示す名前が含まれている必要があります。 リレーションシップは、テーブル、ビュー、またはサブクエリです。 このリレーションシップを持つすべての結合では、スキュー結合の最適化が使用されます。
-- 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
リレーション名と列名を使用してスキュー ヒントを構成する
あるリレーションには複数の結合が存在する可能性があり、そのうちの一部だけが偏りの影響を受ける可能性があります。 スキュー結合の最適化にはオーバーヘッドがあるため、必要な場合にのみ使用することをお勧めします。 このため、スキュー ヒントでは列名を許可します。 スキュー結合の最適化を使用するのは、これらの列を持つ結合のみです。
-- 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
関係名、列名、スキュー値を使用してスキュー ヒントを構成する
ヒントでスキュー値を指定することもできます。 クエリとデータによっては、スキュー値が認識される場合があります (変更されないためなど)。これを行うと、スキュー結合の最適化のオーバーヘッドが軽減されます。 それ以外の場合は、Delta Lake によって自動的に検出されます。
-- 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