2013-06-29 42 views
6

Chúng tôi có một bảng với khoảng 1,5 triệu bản ghi. Bảng này có rất nhiều quan hệ FK đến từ các bảng khác nhau.Làm thế nào để xóa rất nhiều bản ghi từ cơ sở dữ liệu SQL nhanh?

Vấn đề là 1 triệu bản ghi chỉ là các bản sao phải bị xóa. Chúng tôi cố gắng xóa 1.000 bản ghi vào thời điểm đó, nhưng đó là một quá trình rất chậm.

Điều tôi nhớ là sao chép các bản ghi tạm thời phải lưu lại bảng mới. Cắt bớt một bản ghi hiện có và sao chép các bản ghi phải lưu lại. Với khôi phục khóa chính và tất cả các mối quan hệ với các bảng khác. Vì vậy, từ phía khách hàng, bạn không thể thấy bất kỳ sự khác biệt nào.

Bạn không chắc chắn đó có phải là cách hiệu quả hay không.

Nếu tôi muốn thấy việc triển khai cơ bản của nó để tôi có thể theo dõi và áp dụng cho trường hợp của mình. Nếu không, tôi muốn thấy cách làm hiệu quả.

Cảm ơn bạn

+1

Đây có phải là một lần ra dọn dẹp, hoặc không hệ thống của bạn tạo một thói quen sao chép dữ liệu? – Trent

+0

Bạn có chỉ mục trên cột mà bạn lọc ra các hàng mà bạn muốn xóa không? – Ilkka

+0

Đó là một tai nạn – German

Trả lời

2

Công ty chúng tôi có nhiều dữ liệu tạm thời được lưu trữ trong cơ sở dữ liệu. Khi chúng ta cần phải xóa một bó của chúng, chúng tôi chia nó thành vài trăm hàng và xóa chúng từng lúc một. Chúng tôi có một ứng dụng có mục đích duy nhất trong cuộc sống là để chạy một vài thắc mắc như thế này hơn và hơn nữa:

with topFew as (select top 100 * from table) delete topFew 

tôi đề nghị bạn whip lên một cái gì đó đơn giản như thế này, và chỉ để cho nó chạy trong một vài giờ. Làm việc trên một cái gì đó khác trong khi nó đang xử lý.

+0

có, điểm tốt, nó có thể được thực hiện bởi một thứ 3. ứng dụng bên, gửi từng hoạt động xóa như một giao dịch low_priority cho cơ sở dữ liệu, tôi đã cố gắng bỏ phiếu, nhưng hệ thống đã nói đủ cho ngày hôm nay: D –

1

Hiệu suất xóa có thể được cải thiện bằng cách tự tham gia bảng bằng cách sử dụng rowid. Nó thậm chí có thể được tối ưu hóa bằng cách sử dụng số lượng lớn thu thập và FORALL

 DECLARE 

    limit_in integer; 
    CURSOR C1 is 
    Select min(b.rowid) 
     from table_name a, table_name b 
     where a.primary_key = b.primary_key; 

     TYPE C1_rec IS TABLE OF C1%ROWTYPE 
     INDEX BY PLS_INTEGER; 

    C1_record C1_rec 

    BEGIN 
    limit_in:=10000 --- Can be changed based on performance 
    OPEN C1; 
     LOOP 
     FETCH C1 BULK COLLECT INTO C1_record LIMIT limit_in; 
     FORALL indx in 1..c1_record.count 
     DELETE FROM table_name where row_id = C1_record(i); 
     commit; 
     END LOOP; 
    END; 

Bảng sẽ bị xóa có bảng con, Vì vậy, sẽ có một ràng buộc vi phạm.

Vì vậy, trước khi thực hiện đoạn mã trên, Đó là một tùy chọn tốt hơn để thay đổi ràng buộc khóa ngoại để CÓ XÓA HỢP ĐỒNG. Chúng tôi không thể sửa đổi một ràng buộc để thêm xóa tầng. Vì vậy, chìa khóa nước ngoài nên được loại bỏ và tái tạo để có cascade delete

ALTER child_table 
    ADD CONSTRAINT fk_name 
    foreign_key (C1) 
    references parent_table (C2) on delete cascade; 

Xóa thác sẽ dọn dẹp bảng con của bạn cũng ..

+2

đây là một giải pháp Oracle, OP đã gắn thẻ câu hỏi của mình với SQL Server – iruvar

+0

cũng được sử dụng trong máy chủ SQL. – Valli

+1

tôi không biết rằng nó dễ dàng dịch, tôi không nhận thức được bất kỳ tương đương readymade cho 'rowid' và' thu thập số lượng lớn' trong SQL Server – iruvar

Các vấn đề liên quan