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

Chèn MySql vào truy vấn đã chọn quá chậm để sao chép 100 triệu hàng

Bất kỳ INSERT ... SELECT ... truy vấn có có được khóa CHIA SẺ không trên các hàng mà nó đọc từ bảng nguồn trong SELECT. Nhưng bằng cách xử lý các phần hàng nhỏ hơn, khóa không kéo dài quá lâu.

Truy vấn với LIMIT ... OFFSET sẽ ngày càng chậm hơn khi bạn chuyển qua bảng nguồn. Với 10.000 hàng mỗi đoạn, bạn cần chạy truy vấn đó 10.000 lần, mỗi truy vấn phải bắt đầu lại và quét qua bảng để đạt được OFFSET mới.

Bất kể bạn làm gì, việc sao chép 100 triệu hàng sẽ mất một khoảng thời gian. Nó đang làm rất nhiều việc.

Tôi sẽ sử dụng pt-archiver , một công cụ miễn phí được thiết kế cho mục đích này. Nó xử lý các hàng trong "khối" (hoặc tập hợp con). Nó sẽ tự động điều chỉnh kích thước của các phần để mỗi phần mất 0,5 giây.

Sự khác biệt lớn nhất giữa phương pháp của bạn và pt-archiver là pt-archiver không sử dụng LIMIT ... OFFSET , nó đi dọc theo chỉ mục khóa chính, chọn các phần hàng theo giá trị thay vì theo vị trí. Vì vậy, mọi đoạn được đọc hiệu quả hơn.

Nhận xét lại của bạn:

Tôi hy vọng rằng việc làm cho kích thước lô nhỏ hơn - và tăng số lần lặp lại - sẽ làm cho vấn đề về hiệu suất tồi tệ hơn , không tốt hơn.

Lý do là khi bạn sử dụng LIMIT với OFFSET , mọi truy vấn phải bắt đầu lại ở đầu bảng và đếm các hàng lên đến OFFSET giá trị. Điều này ngày càng lâu hơn khi bạn lặp lại qua bảng.

Chạy 20.000 truy vấn đắt tiền bằng OFFSET sẽ mất nhiều thời gian hơn so với việc chạy 10.000 truy vấn tương tự. Phần đắt nhất sẽ không phải là đọc 5.000 hoặc 10.000 hàng, hoặc chèn chúng vào bảng đích. Phần đắt tiền sẽ được bỏ qua ~ 50.000.000 hàng, lặp đi lặp lại.

Thay vào đó, bạn nên lặp lại bảng theo giá trị không phải bằng hiệu số.

INSERT IGNORE INTO Table2(id, field2, field3)
        SELECT f1, f2, f3
        FROM Table1
        WHERE id BETWEEN rowOffset AND rowOffset+limitSize;

Trước vòng lặp, hãy truy vấn MIN (id) và MAX (id) và bắt đầu rowOffset ở giá trị nhỏ nhất và lặp lại đến giá trị lớn nhất.

Đây là cách pt-archiver hoạt động.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Truy vấn tìm kiếm đầu tiên theo chiều rộng trong MySQL?

  2. Liệt kê các giá trị Enum trong php mysql thả xuống

  3. Cách lưu trữ Java Instant trong cơ sở dữ liệu MySQL

  4. làm thế nào để kiểm tra xem một chuỗi trông ngẫu nhiên, hay do con người tạo ra và có thể phát âm?

  5. codeIgniter sử dụng mysql_real_escape_string () thay thế. vấn đề kết nối cơ sở dữ liệu