MySQL: thực hiện di chuyển dữ liệu lớn giữa các bảng


7

Tôi muốn di chuyển dữ liệu giữa 2 bảng InnoDB.

Hiện tại tôi đang chạy truy vấn này:

INSERT INTO table_a SELECT * FROM table_b;

Nếu tập dữ liệu phát triển, cách tốt nhất để tránh quá tải CPU là gì?

Cảm ơn


3
CPU sẽ không phải là vấn đề của bạn, Đĩa i / o sẽ.

Tôi đoán bạn cắt ngắn bảng bạn di chuyển mọi lúc? sau đó, bạn chỉ nên xem xét việc di chuyển sự khác biệt sang lần di chuyển cuối cùng (còn gọi là lưu dấu thời gian khi lần di chuyển cuối cùng được thực hiện và chỉ chuyển các hàng có dấu thời gian lớn hơn thế)

Có thể bạn muốn tạm thời xóa các chỉ mục trước khi di chuyển, sau đó tạo lại chúng sau khi di chuyển thành công.
biziclop

Có, trước khi thực hiện truy vấn tôi vô hiệu hóa các chỉ mục. Nhưng tôi vẫn nhận thấy đĩa / cpu quá tải.

1
Bạn đang sử dụng công cụ lưu trữ nào? Innodb hay myisam? Giống nhau cho cả hai bảng?
atxdba

Câu trả lời:


2

Vì bạn đang sử dụng InnoDB, tôi muốn đề xuất như sau:

BỀN VỮNG # 1

Nếu bạn thực hiện CHERTN, CẬP NHẬT và XÓA, hãy tải số lượng lớn bảng như thế này:

CREATE TABLE table_new LIKE table_a;
INSERT INTO table_new SELECT * FROM table_b;
ALTER TABLE table_a RENAME table_old;
ALTER TABLE table_new RENAME table_a;
DROP TABLE table_old;

Nếu bạn không làm gì ngoài CHERTN và CHỌN, hãy tải các mục mới vào bảng. Giả sử khóa chính của table_atable_bid, thực hiện tải như thế này:

CREATE TABLE table_new LIKE table_a;
INSERT INTO table_new SELECT B.* FROM table_b B
LEFT JOIN table_a A USING (id) WHERE A.id IS NULL;
INSERT INTO table_a SELECT * FROM table_new;
DROP TABLE table_new;

SUGGESTION # 2: Điều chỉnh InnoDB cho nhiều CPU

Hãy chắc chắn rằng bạn đang sử dụng MySQL 5.5. Nếu bạn có MySQL 5.1,38 trở lên, bạn phải cài đặt Plugin InnoDB . Nếu bạn có MySQl 5.1.37 hoặc trước đó, chỉ cần nâng cấp lên MySQL.

Khi bạn đã làm điều đó (hoặc nếu bạn đã có MySQL 5.5), bạn phải điều chỉnh InnoDB cho nhiều CPU. Thay vì phát minh lại bánh xe, đây là những bài viết trước đây của tôi về cách thức và lý do để làm như vậy:

Hãy thử một lần !!!

Tôi có thể đề xuất những thứ khác như bộ đệm, tệp nhật ký, v.v. Tôi chỉ giải quyết hai mối quan tâm này.


Hãy để tôi hiểu đề nghị đầu tiên của bạn. Bạn đang sử dụng bảng tạm thời (tên_bảng) nơi dữ liệu được lưu. Cuối cùng, bạn thực hiện một truy vấn SQL khá giống với truy vấn của tôi ... Bạn có hiệu quả hơn không? Tôi sẽ có vấn đề i / o đĩa?
Mich Dart

Điều gì về dữ liệu được chèn vào A trước khi A kết thúc được sao chép vào B? B không đầy đủ?
KeatsKelleher

1

Trong trường hợp này, thông thường, giải pháp tốt nhất là mysqldump sử dụng --tabtùy chọn như thế này:

mysqldum --tab=/path/to/serverlocaldir --single-transaction <database> table_a

tùy chọn tab tạo ra 2 tệp, một tệp -table_a.sql- chỉ chứa câu lệnh tạo bảng và tệp oher -table_a.txt- chứa dữ liệu được phân tách bằng tab.

Bây giờ bạn có thể tạo bảng mới của bạn

create table table_b like table_a;

Sau đó, bạn chỉ cần tải dữ liệu trong bảng mới của mình LOAD DATAmà không cần quan tâm đến tên của bảng.

LOAD DATA INFILE '/path/to/serverlocaldir/table_a.txt' 
  INTO TABLE table_b FIELDS TERMINATED BY '\t' ...

LOAD DATA thường nhanh hơn 20 lần so với sử dụng các câu lệnh INSERT.

Hi vọng điêu nay co ich


Đây là một giải pháp tốt, nhưng cần có sự can thiệp thủ công hoặc lệnh dựa trên shell. Tôi sẽ coi đó là lựa chọn hợp lệ. Cảm ơn bạn
Mich Dart
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.