Tôi có một bảng DB bao gồm 2,5 tỷ bản ghi. Có trùng lặp với giai điệu 11 triệu. Cách nào nhanh nhất để xóa 11 triệu bản ghi này?Làm cách nào để xóa nhanh hơn?
Trả lời
đầu tiên đưa một chỉ mục trên cột hoặc cột mà xác định và chứa các giá trị nhân bản,
Sau đó, assumimg bảng có một khóa chính (PK),
Delete Table T Where PK <>
(Select Min(PK) From Table
Where ColA = T.ColA
... for each column in set defined above
And ColB = T.ColB)
Chú ý: Cũng có thể sử dụng Tối đa (PK), tất cả những gì bạn đang làm là xác định một bản ghi duy nhất để không xóa khỏi từng bộ bản sao
EDIT: Để loại bỏ việc sử dụng rộng rãi nhật ký giao dịch và phân vùng UNDO, bạn có thể lưu trữ các giá trị dupes trong một bảng tạm thời, và sau đó xóa các dupes f hoặc mỗi cặp trong một giao dịch duy nhất ...
Giả sử chỉ có một cột (gọi nó là Cola, một số) xác định các giá trị nhân bản ...
Create Table Dupes (ColA Number)
Insert Dupes(ColA)
Select Distinct ColA
From Table
Group By ColA
Having Count(*) > 1
recordExists Number := 0 ;
ColAValue Number;
Select Case When Exists (Select Count(*) From Dupes)
Then 1 Else 0 End Into recordExists From Dual;
While recordExists = 1
Loop
Select (Select Max(ColA) From Dupes)
Into ColAValue From Dual;
Begin Transaction
Delete Table T
Where ColA = ColAValue
And pk <> (Select Min(Pk) From Table
Where ColA = ColAValue);
Delete Dupes Where ColA = ColAValue;
Commit Transaction;
Select Case When Exists (Select Count(*) From Dupes)
Then 1 Else 0 End Into recordExists From Dual;
End Loop;
Không thử nghiệm, vì vậy cú pháp có thể neeed massage ...
Nếu bạn chắc chắn rằng bạn không thay đổi tính toàn vẹn của dữ liệu (tính toàn vẹn tham chiếu), vô hiệu hóa các ràng buộc (chỉ mục, các ràng buộc khác), thực hiện xóa, sau đó bật các ràng buộc. Trước tiên, bạn phải thử trước, để xem liệu làm mới các chỉ mục khi bật ít tốn thời gian hơn việc xóa chúng với chúng có được bật hay không.
Một số tối ưu hóa truy vấn cũng có thể hữu ích, nhưng không biết thêm chi tiết, chúng tôi đang thảo luận về mặt lý thuyết.
DELETE
FROM mytable
WHERE rowid IN
(
SELECT rowid
FROM (
SELECT rowid, ROW_NUMBER() OVER (ORDER BY dupfield) rn
FROM mytable r
)
WHERE rn > 1
)
hoặc thậm chí có này:
DELETE
FROM mytable mo
WHERE EXISTS
(
SELECT NULL
FROM mytable mi
WHERE mi.dup_field = mo.dup_field
AND mi.rowid <> mo.rowid
)
Cả hai truy vấn sẽ sử dụng khá hiệu quả HASH SEMI JOIN
, sau này sẽ nhanh hơn nếu không có chỉ mục trên dup_field
.
Bạn có thể bị cám dỗ sao chép các hàng, nhưng lưu ý rằng nhiều thông tin hơn REDO
và UNDO
sẽ được tạo khi sao chép 2G
hàng hơn khi xóa 11M
.
hiệu suất của bản cập nhật như thế nào khi kích thước bảng là 2,5 tỷ? –
Tôi có cảm giác rằng truy vấn này là con chó chậm, nhưng có thể đạt được những gì OP cần. Điều này có thể được viết lại như là một tham gia? –
Sẽ có một sắp xếp trên 'dupfield' (nếu không có chỉ mục trên đó), có thể mất nhiều thời gian. Tham gia vào 'rowid' sẽ là' HASH SEMI JOIN', chỉ là vài phút trên '2G' đối với các hàng' 11M'. Xóa chính nó cũng sẽ mất hàng chục phút, chủ yếu để tạo 'REDO' và' UNDO'. – Quassnoi
Xóa một bản sao khỏi nhiều người là một doanh nghiệp phức tạp và với nhiều bản ghi đó, bạn gặp sự cố.
Một tùy chọn là bật vấn đề trên đầu của nó và sao chép các bản ghi bạn muốn lưu vào bảng mới. Bạn có thể sử dụng cú pháp CREATE TABLE AS SELECT DISTINCT ... NOLOGGING
, cú pháp này sẽ sao chép các bản ghi đã sao chép của bạn mà không sử dụng nhật ký giao dịch, nhanh hơn nhiều. Khi bảng mới của bạn được điền, hãy xóa/đổi tên bảng cũ và đổi tên mới thành vị trí mới.
Oh, và nhớ để tát một chỉ số UNIQUE trên bảng mới để điều này không xảy ra nữa.
Đạo đức của câu chuyện là ... không bao giờ sử dụng DELETE để loại bỏ số lượng lớn các bản ghi, thật khủng khiếp vì nó phải lưu trữ tất cả các bản ghi đã xóa trong nhật ký làm lại. Hoặc là sao chép và chuyển đổi hoặc TRUNCATE.
... và bạn có thể áp dụng cùng một thuật toán cho nhóm sản xuất sản phẩm chỉ cho phép 11.000.000 hàng trùng lặp ;-) Keith. – corlettk
+1 cho câu trả lời này. Tôi chắc chắn sẽ bị cám dỗ để tạo ra một bản sao mới của bảng và chèn vào đó. Điều quan trọng tôi muốn thêm, không đặt bất kỳ chỉ mục nào trên bảng phụ đó cho đến khi bạn sao chép dữ liệu qua - bạn không muốn lần truy cập không cần thiết của nó phải giữ chỉ mục lên đến đầu trong khi chèn dữ liệu.Tôi cũng thích cách tiếp cận này vì nó có thêm một mạng lưới an toàn - bạn không phải loại bỏ bảng cũ cho đến khi chắc chắn 100% bạn đã có tất cả các dữ liệu chính xác. – AdaTheDev
nó sẽ là thú vị để so sánh thời gian cần để sao chép 2,489 tỷ hồ sơ và xóa 11 triệu, sử dụng cùng một vị ngữ –
Việc xóa các hàng hiện có hay tạo bảng mới thích hợp và giảm bảng cũ nhanh hơn phụ thuộc vào nhiều yếu tố. 11 triệu hàng là rất nhiều, nhưng nó chỉ chiếm 0,5% tổng số hàng trong bảng. Hoàn toàn có thể là việc khôi phục mức giảm & có thể chậm hơn nhiều so với xóa, tùy thuộc vào số lượng chỉ mục tồn tại trên bảng nguồn, cũng như nơi các hàng cần xóa tồn tại trên các trang dữ liệu.
Sau đó, có vấn đề về việc liệu bảng nguồn có đang hoạt động hay không. Nếu có chèn & cập nhật đang diễn ra trong khi quá trình dọn dẹp này xảy ra, bản sao thả & sẽ không hoạt động nếu không có số lượng mã bổ sung hợp lý để đồng bộ hóa bảng sau khi thực tế.
Cuối cùng, tại sao cần phải thực hiện thao tác này "nhanh"? Có phải vì hệ thống cần phải ngoại tuyến trong khi quá trình diễn ra không? Bạn có thể viết một thủ tục loại bỏ các dupes trong khi hệ thống đang hoạt động, nhưng không ảnh hưởng đến phần còn lại của hệ thống về mặt tiêu thụ hoàn tác. Chúng tôi đã giải quyết được vấn đề này trong quá khứ bằng cách đầu tiên viết một truy vấn mà thu thập các từ khóa chính của các hàng phải được loại bỏ trong một bảng thứ hai, như vậy:
INSERT
INTO RowsToDeleteTable
SELECT PKColumn
FROM SourceTable
WHERE <conditions used to find rows to remove>
CREATE UNIQUE INDEX PK_RowsToDelete ON RowsToDeleteTable (PKColumn);
Sau đó, chúng tôi có một/block PL SQL mà một trong hai vòng so với hàng trong một con trỏ như sau:
BEGIN
FOR theRow IN (SELECT PKColumn FROM RowsToDeleteTable ORDER BY 1) LOOP
<delete source table for theRow.PKColumn)
<optionally wait a bit>
commit;
END LOOP;
END;
hoặc làm điều gì đó như thế này:
BEGIN
FOR theRow IN (SELECT MIN(PKColumn) FROM RowsToDeleteTable) LOOP
<delete source table for theRow.PKColumn)
<optionally wait a bit>
DELETE RowsToDeleteTable
WHERE PKColumn = theRow.PKColumn;
commit;
END LOOP;
END;
các vòng lặp và "SELECT MAX" rõ ràng là kém hiệu quả, nhưng nó có lợi thế là cho phép bạn t o thực hiện theo tiến trình của thao tác xóa. Chúng tôi đặt một chút mã chờ đợi trong vòng lặp để cho phép chúng tôi kiểm soát hoạt động gặt hái mạnh mẽ như thế nào.
Việc tạo RowsToDeleteTable ban đầu diễn ra rất nhanh và bạn có lợi thế cho phép quá trình thực hiện bao lâu tùy thích. Trong trường hợp như thế này, các "lỗ hổng" còn lại trong phần mở rộng của bạn bằng cách xóa sẽ không quá tệ, vì bạn đang xóa một tỷ lệ phần trăm nhỏ trong tổng số dữ liệu.
- 1. Làm thế nào để làm cho JOINS nhanh hơn?
- 2. Có cách nào nhanh hơn/tốt hơn để xóa bộ nhớ cache của iPhone Simulator hơn xóa thư mục của nó không?
- 3. Inverse String.Replace - Cách làm nhanh hơn?
- 4. Làm thế nào để kịch bản sed này nhanh hơn?
- 5. những gì nhanh hơn: tạo lại hoặc xóa()?
- 6. C++ cách nhanh nhất để xóa hoặc xóa một vector
- 7. Làm cho localhost nhanh hơn?
- 8. Làm Matplotlib chạy nhanh hơn
- 9. Làm cách nào để làm cho việc biên dịch Quartus II nhanh hơn
- 10. Làm thế nào để đọc từ một tập tin văn bản nhanh hơn/thông minh hơn?
- 11. Làm cho JAXB đi nhanh hơn
- 12. khi nào java nhanh hơn C++ (hoặc khi nào JIT nhanh hơn được biên dịch trước)?
- 13. Làm thế nào để làm cho IDE nhật thực để xây dựng nhanh hơn
- 14. Làm cách nào để kết hợp văn bản này nhanh hơn?
- 15. Làm cách nào để triển khai ngôn ngữ có cùng ngôn ngữ nhanh hơn ngôn ngữ?
- 16. Làm cách nào để tôi có thể thực hiện truy vấn SQL 'NOT IN' nhanh hơn?
- 17. Làm cách nào để chạy thử nghiệm trên RoR nhanh hơn?
- 18. Làm cách nào để nhận Vim nhận dạng khóa ESC nhanh hơn?
- 19. Có cách nào nhanh hơn để làm @property, @synthesize và phát hành biến lớp không?
- 20. Trong MySQL, có nhanh hơn để xóa và sau đó chèn hoặc là nó nhanh hơn để cập nhật các hàng hiện có?
- 21. Nhanh hơn javac/kiến?
- 22. Cách nhanh hơn để điền <select> bằng Javascript
- 23. Chứa nhanh hơn StartsWith?
- 24. Có cách nào nhanh hơn để tích hợp chi nhánh tính năng không?
- 25. MongoDB tìm và xóa - cách nhanh nhất
- 26. Websockets nhanh hơn WebRTC?
- 27. strlen nhanh hơn?
- 28. Cái nào nhanh hơn và nhẹ hơn - mysqli & PDO
- 29. Cách nhanh hơn để ghi hình ảnh vào Process.StandardInput.BaseStream
- 30. cách nhanh hơn để tải xuống nhiều tệp
Chỉ để cung cấp chế độ xem hiệu năng hệ thống, truy vấn để nhận số lượng hàng trùng lặp mất 1 giờ 40 phút. –
Tôi nghĩ rằng OP đã xóa tài khoản của anh ấy. – Shimmy
Xin cảm ơn các bạn! Tôi phải sao chép các bản ghi duy nhất vào một bảng, cắt ngắn bảng gốc và sao chép lại dữ liệu duy nhất. – Chattz