2010-03-05 31 views
12

Tôi có một bảng lớn với 19 000 000 bản ghi và tôi gặp sự cố với các hàng trùng lặp. Có rất nhiều câu hỏi tương tự ngay cả ở đây trong SO, nhưng không ai trong số họ dường như cho tôi một câu trả lời thỏa đáng. Một số điểm cần xem xét:Xóa các bản sao từ một bảng lớn

  • Tính duy nhất của hàng được xác định bởi hai cột, location_iddatetime.
  • Tôi muốn giữ thời gian thực hiện càng nhanh càng tốt (< 1 giờ).
  • Sao chép các bảng không phải là rất khả thi vì bảng có kích thước vài gigabyte.
  • Không cần phải lo lắng về mối quan hệ.

Như đã nói, mọi location_id chỉ có thể có một riêng biệt datetime và tôi muốn xóa tất cả các phiên bản trùng lặp. Nó không quan trọng mà một trong số họ sống sót, vì dữ liệu giống hệt nhau.

Bất kỳ ý tưởng nào?

+3

Cân nhắc xóa chỉ mục tạm thời, trình kích hoạt nếu tồn tại. – Pentium10

+0

Điều gì đã xảy ra với phương pháp được đưa ra trong http://stackoverflow.com/questions/1585412/sql-to-delete-duplicate-records-in-a-table? – Mike

+0

@ Pentium10, điểm tốt, có thể tăng tốc mọi thứ, nhưng cũng có thể giết hiệu suất nếu tôi đi qua với giải pháp truy vấn phụ. –

Trả lời

15

Tôi nghĩ rằng bạn có thể sử dụng truy vấn này để xóa các bản ghi trùng lặp từ bảng

ALTER IGNORE TABLE table_name ADD UNIQUE (location_id, datetime) 

Trước khi làm điều này , chỉ cần thử nghiệm với một số dữ liệu mẫu đầu tiên..và sau đó Thử này ....

Lưu ý: Trên phiên bản 5.5, nó hoạt động trên MyISAM chứ không phải InnoDB.

+0

Điều này có vẻ đầy hứa hẹn, trước đây tôi chưa từng nghe về tính năng này. Đang thử nó ngay bây giờ, tôi sẽ cho bạn biết làm thế nào nó quay ra. Và chào mừng bạn đến với SO :) –

+6

Điều này làm việc, cảm ơn bạn. Mất 31 phút để đi qua 16 982 040 hàng với 1 589 908 bản sao.Tôi không thể tin rằng nó có thể được đơn giản này, không có bảng bổ sung hoặc truy vấn phức tạp. :) –

+0

@Vinodkumar Saravana, tôi đang chạy 5.5 với InnoDB, tôi đọc ghi chú của bạn nhưng tôi đã thử nó dù sao chỉ để chắc chắn. (Tất nhiên nó không hoạt động), nhưng bạn có thể giải thích tại sao nó không hoạt động trên InnoDB? – tixastronauta

1
SELECT *, COUNT(*) AS Count 
FROM table 
GROUP BY location_id, datetime 
HAVING Count > 2 
0
UPDATE table SET datetime = null 
WHERE location_id IN (
SELECT location_id 
FROM table as tableBis 
WHERE tableBis.location_id = table.location_id 
AND table.datetime > tableBis.datetime) 

SELECT * INTO tableCopyWithNoDuplicate FROM table WHERE datetime is not null 

DROp TABLE table 

RENAME tableCopyWithNoDuplicate to table 

Vì vậy, bạn giữ cho phù hợp với datetime thấp hơn. Tôi không chắc chắn về perf, nó phụ thuộc vào cột bảng của bạn, máy chủ của bạn vv ...

0

Truy vấn này hoạt động hoàn hảo cho mọi trường hợp: được thử nghiệm cho Engine: MyIsam cho 2 triệu hàng.

ALTER TABLE tên_bảng ADD IGNORE UNIQUE (location_id, datetime)

0

Bạn có thể xóa các bản sao sử dụng các bước sau: 1- Xuất kết quả truy vấn sau đây của thành một file txt:

select dup_col from table1 group by dup_col having count(dup_col) > 1 

2- Add đây là tệp đầu tiên của tệp txt ở trên và chạy truy vấn cuối cùng:

delete from table1 where dup_col in (.....) 

Xin lưu ý rằng '...' là nội dung của tệp txt được tạo i n bước đầu tiên.

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