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:
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