Sdílet prostřednictvím


Adaptivní zpracování dotazů

Adaptivní provádění dotazů (AQE) představuje opětovnou optimalizaci dotazů, ke které dochází během provádění dotazů.

Motivací k opětovné optimalizaci modulu runtime je, že Azure Databricks má na konci výměny náhodného a všesměrového vysílání nejaktuálnější statistiku (označovanou jako fáze dotazu v AQE). V důsledku toho může Azure Databricks zvolit lepší fyzickou strategii, vybrat optimální velikost a číslo oddílu po náhodném prohazování nebo provést optimalizace, které se používají k vyžadování tipů, například zpracování nerovnoměrné distribuce spojení.

To může být velmi užitečné, když shromažďování statistik není zapnuté nebo když jsou statistiky zastaralé. Je také užitečná na místech, kde staticky odvozené statistiky nejsou přesné, například uprostřed složitého dotazu nebo po výskytu nerovnoměrné distribuce dat.

Funkce

Funkce AQE je ve výchozím nastavení povolená. Má 4 hlavní funkce:

  • Dynamicky se mění sloučení spojení sloučení do spojení hash všesměrových přenosů.
  • Dynamicky slučuje oddíly (kombinují malé oddíly do oddílů s rozumnou velikostí) po výměně náhodného prohazování. Velmi malé úlohy mají horší propustnost vstupně-výstupních operací a mají tendenci mít větší nároky na plánování režie a nastavení úloh. Kombinace malých úloh šetří prostředky a zlepšuje propustnost clusteru.
  • Dynamicky zpracovává nerovnoměrnou distribuci spojení sloučení řazení a shuffle hash spojení rozdělením (a replikací v případě potřeby) nerovnoměrnou distribuci úkolů do zhruba rovnoměrně velkých úkolů.
  • Dynamicky rozpoznává a šíří prázdné relace.

Aplikace

AQE se vztahuje na všechny dotazy, které jsou:

  • Bez streamování
  • Obsahují aspoň jednu výměnu (obvykle v případě spojení, agregace nebo okna), jednoho dílčího dotazu nebo obojího.

Ne všechny dotazy použité na AQE jsou nutně znovu optimalizované. Opětovná optimalizace může nebo nemusí přijít s jiným plánem dotazu, než je plán dotazu staticky zkompilovaný. Pokud chcete zjistit, jestli plán dotazu AQE změnil, přečtěte si následující část Plány dotazů.

Plány dotazů

Tato část popisuje, jak můžete prozkoumat plány dotazů různými způsoby.

V této části:

Uživatelské rozhraní Sparku

Uzel AdaptiveSparkPlan

Použité dotazy AQE obsahují jeden nebo více AdaptiveSparkPlan uzlů, obvykle jako kořenový uzel každého hlavního dotazu nebo dílčího dotazu. Před spuštěním dotazu nebo jeho spuštěním isFinalPlan se příznak odpovídajícího AdaptiveSparkPlan uzlu zobrazí jako false; po dokončení provádění dotazu se isFinalPlan příznak změní na true.

Vývojový plán

Diagram plánu dotazu se vyvíjí s průběhem provádění a odráží nejaktuálnější plán, který se provádí. Uzly, které už byly spuštěny (ve kterých jsou k dispozici metriky), se nezmění, ale ty, které se v průběhu času nemůžou v důsledku opětovné optimalizace změnit.

Následuje příklad diagramu plánu dotazu:

Query plan diagram

DataFrame.explain()

Uzel AdaptiveSparkPlan

Použité dotazy AQE obsahují jeden nebo více AdaptiveSparkPlan uzlů, obvykle jako kořenový uzel každého hlavního dotazu nebo dílčího dotazu. Před spuštěním dotazu nebo při jeho spuštění isFinalPlan se příznak odpovídajícího AdaptiveSparkPlan uzlu zobrazí jako false; po dokončení provádění dotazu se isFinalPlan příznak změní na true.

Aktuální a počáteční plán

Pod každým AdaptiveSparkPlan uzlem bude počáteční plán (plán před použitím optimalizace AQE) i aktuální nebo konečný plán v závislosti na tom, jestli se provádění dokončilo. Aktuální plán se bude vyvíjet v průběhu provádění.

Statistika modulu runtime

Každá fáze náhodného prohazování a všesměrového vysílání obsahuje statistiky dat.

Před spuštěním fáze nebo při spuštění fáze jsou statistiky odhady času kompilace a příznak isRuntime je falsenapříklad: Statistics(sizeInBytes=1024.0 KiB, rowCount=4, isRuntime=false);

Po dokončení provádění fáze se statistiky shromažďují za běhu a příznak isRuntime se stane truenapříklad: Statistics(sizeInBytes=658.1 KiB, rowCount=2.81E+4, isRuntime=true)

DataFrame.explain Následuje příklad:

  • Před provedením

    Before execution

  • Během provádění

    During execution

  • Po provedení

    After execution

SQL EXPLAIN

Uzel AdaptiveSparkPlan

Použité dotazy AQE obsahují jeden nebo více uzlů AdaptiveSparkPlan, obvykle jako kořenový uzel každého hlavního dotazu nebo dílčího dotazu.

Žádný aktuální plán

Vzhledem k tomu SQL EXPLAIN , že dotaz nespustí, aktuální plán je vždy stejný jako počáteční plán a neodráží, co by nakonec provedl AQE.

Následuje příklad vysvětlení SQL:

SQL explain

Účinnost

Plán dotazu se změní, pokud se projeví jedna nebo více optimalizací AQE. Účinek těchto optimalizací AQE je demonstrován rozdílem mezi aktuálními a konečnými plány a počátečním plánem a konkrétními uzly plánu v aktuálních a konečných plánech.

  • Dynamická změna sloučení spojení sloučení do spojení hash všesměrového vysílání: různé fyzické spojovací uzly mezi aktuálním/konečným plánem a počátečním plánem

    Join strategy string

  • Dynamicky shodovat oddíly: uzel CustomShuffleReader s vlastností Coalesced

    Custom shuffle reader

    Custom shuffle reader string

  • Dynamicky zpracovává nerovnoměrné spojení: uzel SortMergeJoin s polem isSkew jako true.

    Skew join plan

    Skew join string

  • Dynamicky rozpozná a šíří prázdné relace: část (nebo celý) plán se nahradí uzlem LocalTableScan s relačním polem jako prázdné.

    Local table scan

    Local table scan string

Konfigurace

V této části:

Povolení a zakázání adaptivního spouštění dotazů

Vlastnost
spark.databricks.optimizer.adaptive.enabled

Typ: Boolean

Určuje, jestli chcete povolit nebo zakázat adaptivní spouštění dotazů.

Výchozí hodnota: true

Povolení automatického náhodného náhodného prohazu

Vlastnost
spark.sql.shuffle.partitions

Typ: Integer

Výchozí počet oddílů, které se mají použít při náhodném prohazování dat pro spojení nebo agregace. Nastavení hodnoty auto umožňuje automaticky optimalizované náhodné prohazování, které automaticky určuje toto číslo na základě plánu dotazu a velikosti vstupních dat dotazu.

Poznámka: U strukturovaného streamování nelze tuto konfiguraci změnit mezi restartováními dotazů ze stejného umístění kontrolního bodu.

Výchozí hodnota: 200

Dynamická změna spojení sloučení sloučení do spojení hash všesměrových přenosů

Vlastnost
spark.databricks.adaptive.autoBroadcastJoinThreshold

Typ: Byte String

Prahová hodnota pro aktivaci přepnutí na všesměrové připojení za běhu.

Výchozí hodnota: 30MB

Dynamicky slučovat oddíly

Vlastnost
spark.sql.adaptive.coalescePartitions.enabled

Typ: Boolean

Určuje, jestli chcete povolit nebo zakázat rozdělení oddílů.

Výchozí hodnota: true
spark.sql.adaptive.advisoryPartitionSizeInBytes

Typ: Byte String

Cílová velikost po zvětšování. Sloučené velikosti oddílů se budou blížit, ale nebudou větší než tato cílová velikost.

Výchozí hodnota: 64MB
spark.sql.adaptive.coalescePartitions.minPartitionSize

Typ: Byte String

Minimální velikostoddílůch Sloučené velikosti oddílů nebudou menší než tato velikost.

Výchozí hodnota: 1MB
spark.sql.adaptive.coalescePartitions.minPartitionNum

Typ: Integer

Minimální počet oddílů po součtení. Nedoporučuje se, protože nastavení explicitně přepisuje
spark.sql.adaptive.coalescePartitions.minPartitionSize.

Výchozí hodnota: 2x ne. jader clusteru

Dynamické zpracování nerovnoměrné distribuce spojení

Vlastnost
spark.sql.adaptive.skewJoin.enabled

Typ: Boolean

Jestli chcete povolit nebo zakázat zpracování nerovnoměrné distribuce spojení.

Výchozí hodnota: true
spark.sql.adaptive.skewJoin.skewedPartitionFactor

Typ: Integer

Faktor, který při vynásobení velikostí mediánu oddílů přispívá k určení, zda je oddíl nerovnoměrně zkosený.

Výchozí hodnota: 5
spark.sql.adaptive.skewJoin.skewedPartitionThresholdInBytes

Typ: Byte String

Prahová hodnota, která přispívá k určení, jestli je oddíl nerovnoměrný.

Výchozí hodnota: 256MB

Oddíl se považuje za nerovnoměrnou distribuci, pokud jsou oba (partition size > skewedPartitionFactor * median partition size) a (partition size > skewedPartitionThresholdInBytes) jsou true.

Dynamické zjišťování a šíření prázdných relací

Vlastnost
spark.databricks.adaptive.emptyRelationPropagation.enabled

Typ: Boolean

Určuje, jestli chcete povolit nebo zakázat šíření dynamické prázdné relace.

Výchozí hodnota: true

Nejčastější dotazy

V této části:

Proč AQE nevysílala malou tabulku spojení?

Pokud velikost relace očekávaného vysílání spadá pod tuto prahovou hodnotu, ale stále není všesměrové:

  • Zkontrolujte typ spojení. Vysílání není podporováno pro určité typy spojení, například levý vztah LEFT OUTER JOIN nelze vysílat.
  • Může to být také to, že relace obsahuje velké množství prázdných oddílů, v takovém případě může většina úkolů rychle dokončit spojení se sloučením řazení nebo může být optimalizována pomocí zpracování nerovnoměrné spojení spojení. AQE zabraňuje změně takových spojení sloučení řazení na všesměrové spojení hash, pokud je procento neprázdných oddílů nižší než spark.sql.adaptive.nonEmptyPartitionRatioForBroadcastJoin.

Mám stále používat nápovědu ke strategii připojení k vysílání s povolenou funkcí AQE?

Ano. Staticky plánované spojení všesměrového vysílání je obvykle výkonnější než dynamicky plánované AQE jako AQE nemusí přepnout na všesměrové spojení, dokud se nepromíchá pro obě strany spojení (čas, kdy jsou získány skutečné velikosti relací). Pokud tedy znáte svůj dotaz dobře, může být použití nápovědy vysílání stále dobrou volbou. AQE bude respektovat rady dotazů stejným způsobem jako statická optimalizace, ale může stále používat dynamické optimalizace, které nejsou ovlivněny radami.

Jaký je rozdíl mezi nápovědou ke zkosení spojení a optimalizací spojení nerovnoměrné distribuce AQE? Který z nich mám použít?

Místo použití nápovědy ke nerovnoměrné distribuci spojení AQE se doporučuje spoléhat na zpracování nerovnoměrného spojení, protože nerovnoměrné spojení AQE je zcela automatické a obecně funguje lépe než protějšek nápovědy.

Proč AQE automaticky neupravoval pořadí připojení?

Změna pořadí dynamického spojení není součástí AQE.

Proč AQE nerozpoznal nerovnoměrnou distribuci dat?

Aby AQE zjistil oddíl jako zkosený oddíl, musí být splněné dvě podmínky velikosti:

  • Velikost oddílu spark.sql.adaptive.skewJoin.skewedPartitionThresholdInBytes je větší než (výchozí 256 MB)
  • Velikost oddílu je větší než medián všech oddílů, kolikrát je nerovnoměrný faktor spark.sql.adaptive.skewJoin.skewedPartitionFactor oddílu (výchozí 5).

Kromě toho je podpora zpracování nerovnoměrné distribuce omezena pro určité typy spojení, například v LEFT OUTER JOIN, lze optimalizovat pouze nerovnoměrnou distribuci na levé straně.

Starší verze

Pojem Adaptivní spouštění existoval od Sparku 1.6, ale nový AQE ve Sparku 3.0 se zásadně liší. Z hlediska funkčnosti Spark 1.6 pouze část "dynamicky slučuje oddíly". Z hlediska technické architektury je nová architektura AQE architekturou dynamického plánování a opětovného plánování dotazů na základě statistik modulu runtime, která podporuje řadu optimalizací, jako jsou ty, které jsme popsali v tomto článku, a lze je rozšířit, aby bylo možné optimalizovat více potenciálních optimalizací.