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

Xóa các bản ghi từ một bảng đã nối vào một bảng SQL khác

Bạn không cần sử dụng OUTER JOIN ngoại trừ việc kiểm tra bao nhiêu hàng sẽ tương ứng. sẽ không bị xóa.

Ví dụ về truy vấn như vậy xem bên dưới (Tôi sử dụng dữ liệu thử nghiệm đã tạo được cung cấp ở cuối câu trả lời)

with del as (
select delta.id, delta.version,
decode(big.id,null,0,1) is_deleted
from delta
left outer join big 
on delta.id = big.id and delta.version = big.version
)
select is_deleted, count(*) cnt, max(id||'.'||version) eg_id_vers
from del
group by is_deleted;

IS_DELETED        CNT  EG_ID_VERS                                                                   
---------- ---------- ----------
         1      20000 99995.0   
         0         20 100100.0   

Với kích thước dữ liệu của mình, bạn nên sử dụng HASH JOIN với full table scan trên cả hai bảng để có được hiệu suất có thể chấp nhận được.

Về cơ bản có hai tùy chọn để thực hiện DELETE

Chế độ xem tham gia có thể cập nhật

Lưu ý rằng trong trường hợp này, bảng nhỏ của bạn phải có một chỉ mục duy nhất trên ID, VERSION (hoặc khóa chính)

create unique index delta_idx on delta(id,version);

Trái ngược với bảng LỚN nên không có ràng buộc như vậy . Điều này rất quan trọng vì nó chỉ ra rõ ràng rằng bảng LỚN của bạn là một bảng bảo quản khóa duy nhất trong chế độ xem tham gia.

Đơn giản, hãy đặt một phép nối vào bảng nhỏ không thể trùng lặp các hàng khỏi bàn lớn do sự tương phản độc đáo

Xem tại đây thêm thông tin về Cập nhật chế độ xem tham gia

delete from 
(
select delta.id, delta.version, big.id big_id, big.version
from big 
join delta 
on delta.id = big.id and delta.version = big.version
)

delete ở trên xóa các hàng khỏi BIG bảng vì đây là bảng bảo quản khóa duy nhất (xem thảo luận ở trên)

DML này dẫn đến một HASH JOIN

Xóa bằng EXISTS

Nếu bảng nhỏ của bạn không có khóa chính (tức là bảng có thể chứa các hàng trùng lặp có cùng ID and VERSION ) bạn phải dự phòng giải pháp được đề xuất trong câu trả lời khác .

DELETE FROM big 
    WHERE EXISTS (SELECT null
                  FROM delta
                  WHERE delta.id = big.id and delta.version = big.version
                 ) 

Không cần lập chỉ mục và bạn sẽ có kế hoạch thực thi với HASH JOIN RIGHT SEMI , có nghĩa là cả hai cách tiếp cận không thực sự khác nhau.

Dữ liệu mẫu để kiểm tra

create table big as
select 
trunc(rownum/10) id, mod(rownum,10) version,
lpad('x',10,'Y') pad
from dual connect by level <= 1000000;

/* the DELTA table has 50 times less rows,
allow some rows out of range of the BIG table - those rows will not be deleted **/
drop table delta;
create table delta as
select 
trunc(rownum*50/10) id, mod(rownum*50,10) version
from dual connect by level <= 1001000/50;

create unique index delta_idx on delta(id,version);


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. AUTONOMOUS_TRANSACTION

  2. Chuyển đổi ngày XSD xs:dateTime thành Ngày Oracle

  3. So sánh các ngày sử dụng Dynamic Action trên DatePicker Oracle Apex

  4. Hàm ROWIDTOCHAR () trong Oracle

  5. Làm thế nào để có được hồ sơ nhân viên mới nhất trong oracle?