sql >> Databáze >  >> RDS >> Oracle

Existuje způsob, jak zlepšit dotaz MERGE?

Pokud byste měli masivní problémy s vaším přístupem, velmi pravděpodobně vám chybí index ve sloupci clean.id , což je vyžadováno pro váš přístup při MERGE používá dual jako zdroj pro každý řádek.

To je méně pravděpodobné, když říkáte id je primární klíč .

Takže v zásadě uvažujete správně a uvidíte plán provedení podobné jako níže:

---------------------------------------------------------------------------------------------------
| Id  | Operation                       | Name            | Rows  | Bytes | Cost (%CPU)| Time     |
---------------------------------------------------------------------------------------------------
|   0 | MERGE STATEMENT                 |                 |       |       |     2 (100)|          |
|   1 |  MERGE                          | CLEAN           |       |       |            |          |
|   2 |   VIEW                          |                 |       |       |            |          |
|   3 |    NESTED LOOPS OUTER           |                 |     1 |    40 |     2   (0)| 00:00:01 |
|   4 |     TABLE ACCESS FULL           | DUAL            |     1 |     2 |     2   (0)| 00:00:01 |
|   5 |     VIEW                        | VW_LAT_A18161FF |     1 |    38 |     0   (0)|          |
|   6 |      TABLE ACCESS BY INDEX ROWID| CLEAN           |     1 |    38 |     0   (0)|          |
|*  7 |       INDEX UNIQUE SCAN         | CLEAN_UX1       |     1 |       |     0   (0)|          |
---------------------------------------------------------------------------------------------------
 
Predicate Information (identified by operation id):
---------------------------------------------------
 
   7 - access("CLEAN"."ID"=:ID)

Prováděcí plán je tedy v pořádku a funguje efektivně, ale má jeden problém.

Pamatujte, že vždy používáte index, budete spokojeni se zpracováním několika řádků, ale nezmění se to .

Pokud zpracováváte miliony záznamů, můžete se vrátit k dvoufázovému zpracování

  • vložit všechny řádky do dočasné tabulky

  • provést jediné MERGE pomocí dočasné tabulky

Velká výhoda je, že Oracle může otevřít hash join a zbavit se přístupu k indexu pro každý z milionů řádky.

Zde je příklad testu clean tabulka iniciovaná 1 milionem id (nezobrazeno) a provádění 1M vložení a 1M aktualizací:

n  = 1000000
data2 = [{"id" : i, "xcount" :1} for i in range(2*n)]  

sql3 = """
    insert into tmp (id,count)
    values (:id,:xcount)"""
sql4 = """MERGE into clean USING tmp on (clean.id = tmp.id)
          when not matched then insert (id, count)  values (tmp.id, tmp.count)
          when matched then update set clean.count= clean.count + tmp.count"""    

cursor.executemany(sql3, data2)
cursor.execute(sql4)

Test probíhá za cca. 10 sekund, což je méně než polovina vašeho přístupu pomocí MERGE pomocí dual .

Pokud to stále nestačí, budete muset použít paralelní možnost .



  1. VYBERTE více řádků, KDE odpovídají dvěma podmínkám

  2. Jak COALESCE() funguje v MariaDB

  3. Přidání nuly do pole, pokud se v poli vyskytují prázdné hodnoty

  4. Jak automaticky aktualizovat tabulku v MYSQL pomocí TRIGGER