Oracle
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> Oracle

Có cách nào để cải thiện truy vấn MERGE không?

Nếu bạn muốn có một đồ sộ vấn đề với cách tiếp cận của bạn, rất có thể bạn đang thiếu chỉ mục trên cột clean.id , điều đó là bắt buộc đối với phương pháp của bạn khi MERGE sử dụng dual làm nguồn cho mỗi hàng.

Điều này ít xảy ra hơn khi bạn đang nói id là một khóa chính .

Vì vậy, về cơ bản bạn đang suy nghĩ đúng và bạn sẽ thấy kế hoạch thực thi tương tự như bên dưới:

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

Vì vậy, kế hoạch thực thi tốt và hoạt động hiệu quả, nhưng nó có một vấn đề.

Hãy nhớ luôn sử dụng một chỉ mục, bạn sẽ hài lòng khi xử lý một vài hàng, nhưng nó sẽ không chia tỷ lệ .

Nếu bạn đang xử lý một hàng triệu trong số các bản ghi, bạn có thể quay lại xử lý hai bước,

  • chèn tất cả các hàng trong một bảng tạm thời

  • thực hiện một MERGE câu lệnh sử dụng bảng tạm thời

Lợi thế lớn là Oracle có thể mở một hash join không và loại bỏ quyền truy cập chỉ mục cho mỗi triệu hàng.

Dưới đây là một ví dụ về kiểm tra clean bảng bắt đầu bằng 1 triệu id (không hiển thị) và thực hiện chèn 1M và cập nhật 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)

Thử nghiệm chạy trong khoảng thời gian. 10 giây, tức là chưa đến một nửa thời gian bạn tiếp cận với MERGE sử dụng dual .

Nếu điều này vẫn chưa đủ, bạn sẽ phải sử dụng tùy chọn song song .



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. khi chèn ký tự Persian trong oracle db, tôi thấy dấu chấm hỏi

  2. Áp dụng hàm COUNT trên một nhóm con của các nhóm

  3. Triển khai cx_Oracle trên các phiên bản khác nhau của Oracle Client

  4. Phân vùng hàng ngày Oracle DB

  5. Cách xử lý ORA-02014:không thể chọn CẬP NHẬT từ chế độ xem với DISTINCT, GROUP BY, v.v.