Článek přečtěte do 6 min.

In-Memory Deep Vectorization Framework byl poprvé představen v Oracle Database 21c. První funkcí, která využila výhody nového rámce, bylo Vektorizovaná spojení v paměti.

V Oracle Database 23c In-Memory Deep Vectorization byla rozšířena tak, aby podporovala následující další typy spojení:

•    Víceúrovňová spojení hash
•    Klíč vícenásobného připojení
•    Semi se připojí
•    Vnější spojení
•    Úplná skupina podle agregace

Toto vylepšení umožňuje další výkon využitím vektorových instrukcí Single Instruction, Multiple Data (SIMD). Pro příklady, které následují spolu se schématem SSB, jsem použil Oracle Database 23c Free.

Ještě jeden detail. Podobně jako u Připojit se ke skupinám je hluboká vektorizace v paměti rozhodnutí za běhu zachycené SQL Monitorem. Použití hloubkové vektorizace v paměti lze zobrazit v aktivní zprávě SQL Monitor kliknutím na dalekohled operace spojení hash.

Například:

SQL Monitor hluboké vektorové statistiky

Všimněte si, že první statistika „DeepVec Hash Joins“ je nastavena na 1. To znamená, že bylo provedeno hluboké vektorové spojení. Existuje druhý způsob, jak zobrazit stejné informace pomocí SQL.

Následující příkaz SQL zobrazí stejné informace ze základních tabulek SQL Monitor:

vypnout echo
nastavit trimspool na
nastavit trim na
nastavit stránky 0
velikost sady 1000
nastavit dlouhé 1000000
nastavit longchunksize 1000000

PROMPT Deep Vectorization Použití: ;
VÝZVA ------------------------- ;
VÝZVA ;

VYBRAT
  ' ' || deepvec.rowsource_id || ' - ' row_source_id,
    POUZDRO
      KDYŽ deepvec.deepvec_hj NENÍ NULL
      PAK
        'použité hluboké vektorové hash spojení: ' || deepvec.deepvec_hj ||
        ', příznaky spojení hlubokého vektorového hash: ' || deepvec.deepvec_hj_flags
      JINÝ
        'deep vector HJ NEBYL využíván'
    END deep_vector_hash_join_usage_info
Z
  (SELECT EXTRACT(DBMS_SQL_MONITOR.REPORT_SQL_MONITOR_XML,
    q'#//operation[@name='HASH JOIN' a @parent_id]#') xmldata
   Z DUAL) hj_operation_data,
  XMLTABLE('/operace'
    PASSING hj_operation_data.xmldata
    SLOUPCE
     "ROWSOURCE_ID" VARCHAR2(5) PATH '@id',
     "DEEPVEC_HJ" VARCHAR2(5) PATH 'rwsstats/stat[@id="11"]',
     "DEEPVEC_HJ_FLAGS" VARCHAR2(5) PATH 'rwsstats/stat[@id="12"]') deepvec;

Zobrazí se v následujícím formátu:

Použití hluboké vektorizace:
--------------------------

   2 - použitá spojení hlubokého vektorového hash: 1, příznaky spojení hlubokého vektorového hash: 24576

Následuje příklad semi-spojení, které nyní využívá hloubkovou vektorizaci v paměti:

select /*+ MONITOR */ count(l.lo_custkey)
z řádky l
kde l.lo_partkey IN (vyberte p.p_partkey z části p)
a l.lo_quantity <= 3;

Výše uvedený dotaz vedl k následujícímu plánu provádění v mé databázi 23c Free:

-------------------------------------------------- -------------------------------------------------- ----------------
| Id | Provoz | Jméno | Řádky | Bajty |TempSpc| Cena (%CPU)| Čas | Pstart| Pstop |
-------------------------------------------------- -------------------------------------------------- ----------------
| 0 | VYBERTE PROHLÁŠENÍ | | | | | 5113 (100)| | | |
| 1 | SEŘADIT SOUHRN | | 1 | 18 | | | | | |
|* 2 | HASH JOIN RIGHT SEMI | | 1640 K| 28 mil.| 12M| 5113 (8)| 00:00:01 | | |
| 3 | TABLE ACCESS INMEMORY FULL | ČÁST | 800 tisíc| 3906 K| | 73 (3)| 00:00:01 | | |
| 4 | ROZSAH PŘÍČEK VŠE | | 1640 K| 20 mil.| | 2448 (15)| 00:00:01 | 1 | 3 |
|* 5 | TABLE ACCESS INMEMORY FULL| ŘÁDKOVÁ OBJEDNÁVKA | 1640 K| 20 mil.| | 2448 (15)| 00:00:01 | 1 | 3 |
-------------------------------------------------- -------------------------------------------------- ----------------

Informace o predikátu (identifikované pomocí ID operace):
-------------------------------------------------- -

   2 - přístup ("L"; "LO_PARTKEY" = "P". "P_PARTKEY")
   5 - paměť ("L". "NÍZKÉ MNOŽSTVÍ" <=3)
       filtr("L". "NÍZKÉ MNOŽSTVÍ"<=3)


Vybráno 25 řádků.

SQL>
SQL> vypnout echo
Použití hluboké vektorizace:
--------------------------

   2 - použitá spojení hlubokého vektorového hash: 1, příznaky spojení hlubokého vektorového hash: 24576

Všimněte si, že v sekci Použití hluboké vektorizace, operace 2, bylo HASH JOIN RIGHT SEMI identifikováno jako používající hluboké vektorové hash spojení.

Jak jsem již zmínil, jedním z klíčových způsobů, jak hluboké vektorové spojení dosahuje vyššího výkonu, je schopnost využít vektorové zpracování Single Instruction, Multiple Data (SIMD). Tento rozdíl můžeme vidět, pokud porovnáme statistiky ze spuštění s vypnutou a poté povolenou vektorizací In-Memory. Bohužel od roku 21c jsou statistiky IM SIMD dostupné pouze na systémové úrovni. Mluvil jsem o tomto problému v relaci Ask TOM Office Hours, kterou jsme dělali na In-Memory Vector Joins v 21c. Můžete se vrátit a zhlédnout video zde. Řešením bylo použít upravenou verzi starého nástroje runstats Toma Kytea k porovnání statistik na úrovni systému spíše než statistik na úrovni relace. Starý nástroj runstats a upravený nástroj run_sysstats můžete vidět na mém webu Github zde.

Slovo opatrnosti. Statistiky na systémové úrovni jsou agregovány napříč všemi databázovými relacemi. V tomto experimentu jsem provozoval svou databázi 23c Free jako v podstatě systém pro jednoho uživatele na mém vlastním virtuálním počítači. Tento přístup nebude fungovat dobře, pokud máte více uživatelů, kteří spouštějí dotazy v paměti.

Následuje výstup ze dvou provedení předchozího dotazu, prvního s deaktivovanou In-Memory Deep Vectorization (tj. inmemory_deep_vectorization = false) a poté s povolenou In-Memory Deep Vectorization (tj. inmemory_deep_vectorization = true):

Název Run1 Run2 Dif
STAT...CPU používaný touto relací 5 41 36
STAT...IM skenované řádky projektováno 2 440 148 51 -2 440 097
STAT...IM simd KV přidat hovory 0 795 795
STAT...IM simd KV přidat řádky 0 800 000 800 000
STAT...IM simd KV sonda volá 0 51 51
STAT...IM simd KV sonda chain_buckets 0 7,437 7,437
STAT...IM simd KV klíče sondy 0 1,640,148 1,640,148
STAT...IM simd KV sonda řádky 0 1,640,148 1,640,148
STAT...IM simd KV sonda serial_buckets 0 420 420
STAT...IM dekódovací symbol simd volání 3,126 2 -3,124
STAT...IM simd dekódování volání rozbalení 0 2 2
STAT...IM simd dekódovat rozbalit selektivní volání 0 2 2
STAT...IM simd hash volání 0 53 53
STAT...IM simd hash rows 0 2,440,148 2,440,148
STAT...fyzické hodnoty 28 13 -15
STAT...logické čtení relace 214 127 214 005 -122
STAT...session pga paměť -524,288 0 524,288

Všimněte si, že existuje podstatný rozdíl v použití SIMD ve sloupci Run2, kde byl příkaz spuštěn s povolenou hloubkovou vektorizací v paměti.

Bylo provedeno ještě jedno opravdu důležité vylepšení. Schopnost podporovat víceúrovňové spojení. Proč je to tak důležité vylepšení? Protože umožňuje pracovat na spojení mezi zdrojem řádků nebo výsledkem předchozího spojení a tabulkou. Proto víceúrovňové spojení.

K zobrazení víceúrovňového spojení použijeme následující dotaz:

vybrat /*+ MONITOR NO_VECTOR_TRANSFORM */
d_year, c_nation, s_region, lo_shipmode , sum(lo_extendedprice)
z části p, zákazník c, objednávka l, dodavatel s, datum_dim d
kde s.s_suppkey = l.lo_suppkey a l.lo_custkey = c.c_custkey
a l.lo_partkey = p.p_partkey a l.lo_orderdate = d.d_datekey
seskupit podle d_year, c_nation, s_region, lo_shipmode;

Tento dotaz vytvořil následující plán provádění a v části „Použití hluboké vektorizace“ si všimněte, že spojení hlubokých vektorů bylo provedeno prostřednictvím každého spojení hash v plánu provádění!

-------------------------------------------------- -------------------------------------------------- -------------------
| Id | Provoz | Jméno | Řádky | Bajty |TempSpc| Cena (%CPU)| Čas | Pstart| Pstop |
-------------------------------------------------- -------------------------------------------------- -------------------
| 0 | VYBERTE PROHLÁŠENÍ | | | | | 145K(100)| | | |
| 1 | HASH GROUP BY | | 2166 | 203 tis.| | 145 K (2)| 00:00:06 | | |
|* 2 | HASH JOIN | | 27 mil.| 2485 mil.| | 145K (1)| 00:00:06 | | |
| 3 | PART JOIN FILTER CREATE | :BF0000 | 2556 | 30672 | | 1 (0)| 00:00:01 | | |
| 4 | TABLE ACCESS INMEMORY FULL | DATE_DIM | 2556 | 30672 | | 1 (0)| 00:00:01 | | |
|* 5 | HASH JOIN | | 27 mil.| 2175 mil.| | 145K (1)| 00:00:06 | | |
| 6 | TABLE ACCESS INMEMORY FULL | DODAVATEL | 20 000 | 351 tis.| | 3 (0)| 00:00:01 | | |
|* 7 | HASH JOIN | | 27 mil.| 1719 mil.| 9672 K| 144K (1)| 00:00:06 | | |
| 8 | TABLE ACCESS INMEMORY FULL | ZÁKAZNÍK | 300 tisíc| 6152K| | 33 (7)| 00:00:01 | | |
|* 9 | HASH JOIN | | 27 mil.| 1172 mil.| 12M| 70700 (2)| 00:00:03 | | |
| 10 | TABLE ACCESS INMEMORY FULL | ČÁST | 800 tisíc| 3906 K| | 73 (3)| 00:00:01 | | |
| 11 | ROZSAH PŘÍČKY JOIN-FILTER| | 27 mil.| 1042 mil.| | 2701 (23)| 00:00:01 |:BF0000|:BF0000|
| 12 | TABLE ACCESS INMEMORY FULL| ŘÁDKOVÁ OBJEDNÁVKA | 27 mil.| 1042 mil.| | 2701 (23)| 00:00:01 |:BF0000|:BF0000|
-------------------------------------------------- -------------------------------------------------- -------------------

Informace o predikátu (identifikované pomocí ID operace):
-------------------------------------------------- -

   2 - přístup("L"."LO_ORDERDATE"="D"."D_DATEKEY")
   5 - přístup ("S". "S_SUPPKEY" = "L". "LO_SUPPKEY")
   7 - přístup ("L". "LO_CUSTKEY"= "C". "C_CUSTKEY")
   9 - přístup ("L"; "LO_PARTKEY" = "P". "P_PARTKEY")


Vybráno 37 řádků.

SQL>
SQL> vypnout echo
Použití hluboké vektorizace:
--------------------------

   2 - použitá spojení hlubokého vektorového hash: 1, příznaky spojení hlubokého vektorového hash:
   5 - použitá spojení hlubokého vektorového hash: 1, příznaky spojení hlubokého vektorového hash: 8192
   7 - použitá spojení hlubokého vektorového hash: 1, příznaky spojení hlubokého vektorového hash: 8192
   9 - použitá spojení hlubokého vektorového hash: 1, příznaky spojení hlubokého vektorového hash: 24576

Toto je velmi vzrušující vylepšení. Všimněte si, že filtr Bloom nebyl vyžadován a pro tento dotaz jsem zakázal vektorovou transformaci, abych ukázal, jak funguje víceúrovňové spojení. Hluboká spojení vektorů nepodporují přímo vektorovou transformaci, ale jiná spojení hash ve stejném plánu mohou využít výhody hlubokých spojení vektorů. Ještě jedna věc, kterou je třeba poznamenat. Víceúrovňové hluboké vektorové spoje podporují levé hluboké, pravé hluboké a některé typy huňatých spojů.

Zdroj: Oracle