Oracle
 sql >> база данни >  >> RDS >> Oracle

Има ли начин за подобряване на MERGE заявка?

Ако искате масивна проблеми с вашия подход, много вероятно ви липсва индекс в колоната clean.id , което се изисква за вашия подход, когато MERGE използва dual като източник за всеки ред.

Това е по-малко вероятно, докато казвате id е първичен ключ .

И така основно мислите правилно и ще видите план за изпълнение подобен на този по-долу:

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

Така че планът за изпълнение е добър и работи ефективно, но има един проблем.

Не забравяйте, че винаги използвате индекс, ще бъдете щастливи, докато обработвате няколко реда, но той няма да се мащабира .

Ако обработвате милиони от записи, можете да се върнете към обработка в две стъпки,

  • вмъкнете всички редове във временна таблица

  • извършете едно MERGE израз с помощта на временната таблица

Голямото предимство е, че Oracle може да отвори hash join и се отървете от достъпа до индекса за всеки от милиона редове.

Ето един пример за тест на clean таблица, инициирана с 1M id (не е показано) и извършване на 1M вмъкване и 1M актуализации:

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)

Тестът се изпълнява за прибл. 10 секунди, което е по-малко от половината ви приближаване с MERGE използвайки dual .

Ако това все още не е достатъчно, ще трябва да използвате паралелна опция .



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Имам нужда от помощ за преобразуване на T-SQL заявка в поддържана от Oracle заявка

  2. Нулирайте последователността на автоматично нарастване pl-sql

  3. Как мога да получа стойност на CDATA от xml

  4. Как да вмъкнете клеймо за време в Oracle в конкретен формат

  5. Какво означава %Type в Oracle sql?