Oracle
 sql >> Teknologi Basis Data >  >> RDS >> Oracle

Apakah ada cara untuk meningkatkan kueri MERGE?

Jika Anda ingin memiliki besar masalah dengan pendekatan Anda, Anda sangat mungkin kehilangan indeks pada kolom clean.id , yang diperlukan untuk pendekatan Anda saat MERGE menggunakan dual sebagai sumber untuk setiap baris.

Ini lebih kecil kemungkinannya saat Anda mengatakan id adalah kunci utama .

Jadi pada dasarnya Anda melakukan pemikiran yang benar dan Anda akan melihat rencana eksekusi mirip seperti di bawah ini:

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

Jadi rencana pelaksanaannya baik-baik saja dan bekerja secara efektif, tetapi ada satu masalah.

Ingat selalu Anda menggunakan indeks, Anda akan senang saat memproses beberapa baris, tetapi tidak akan menskala .

Jika Anda memproses jutaan catatan, Anda mungkin kembali ke pemrosesan dua langkah,

  • menyisipkan semua baris dalam tabel sementara

  • melakukan satu MERGE pernyataan menggunakan tabel sementara

Keuntungan besar adalah bahwa Oracle dapat membuka hash join dan singkirkan akses indeks untuk setiap juta baris.

Berikut contoh pengujian clean tabel dimulai dengan 1 juta id (tidak ditampilkan) dan melakukan penyisipan 1 juta dan pembaruan 1 juta:

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)

Tes berjalan dalam kira-kira. 10 detik, yang kurang dari setengah dari Anda mendekati dengan MERGE menggunakan dual .

Jika ini masih belum cukup, Anda harus menggunakan opsi paralel .



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Rutin yang Ditentukan Pengguna dengan DBMS_STATS, Bagian II

  2. Fungsi REPEAT setara di Oracle

  3. SQL misterius memblokir prosedur tersimpan saya agar tidak dieksekusi di ORACLE

  4. Cara mengelompokkan dengan syarat khusus

  5. PL/SQL:kesalahan numerik atau nilai:buffer string karakter terlalu kecil %ROWTYPE