2012-01-09 37 views
10

Tôi đang cố tải số lượng lớn khoảng 12 triệu bản ghi vào bảng InnoDB trong một (địa phương) mysql bằng LOAD DATA INFILE (từ CSV) và việc tìm kiếm mất rất nhiều thời gian để hoàn thành.cải thiện hiệu suất tải dữ liệu tải mysql

Loại khóa chính là UUID và các khóa không được phân loại trong các tệp dữ liệu.

tôi đã chia các tập tin dữ liệu vào file chứa 100000 hồ sơ và nhập nó như:

mysql -e 'ALTER TABLE customer DISABLE KEYS;' 
for file in *.csv 
    mysql -e "SET sql_log_bin=0;SET FOREIGN_KEY_CHECKS=0; SET UNIQUE_CHECKS=0; 
    SET AUTOCOMMIT=0;LOAD DATA INFILE '${file}' INTO TABLE table 
    FIELDS TERMINATED BY ',' LINES TERMINATED BY '\n'; COMMIT" 

này hoạt động tốt trong vài trăm ngàn hồ sơ đầu tiên nhưng sau đó chèn giờ cho mỗi tải tiếp theo dường như để giữ phát triển (từ khoảng 7 giây để khoảng 2 phút cho mỗi tải trước khi tôi giết nó.)

tôi đang chạy trên một máy với 8GB RAM và đã thiết lập các thông số InnoDB để:

innodb_buffer_pool_size =1024M 
innodb_additional_mem_pool_size =512M 
innodb_log_file_size = 256M 
innodb_log_buffer_size = 256M 

Tôi cũng đã thử tải một CSV duy nhất chứa tất cả các hàng không có may mắn - điều này đã vượt quá 2 giờ trước khi tôi giết nó.

Có điều gì khác có thể tăng tốc độ này vì điều này có vẻ như là một thời gian quá nhiều để chỉ tải 12 triệu bản ghi?

+0

[DISABLE KEYS không xuất hiện để hoạt động trong InnoDB] (http://serverfault.com/questions/291100/with-mysql-how-long-does-an-alter-table-disable-keys-statement- cuối cùng), câu trả lời về việc bỏ và thêm các chỉ mục phụ là tốt. – KCD

+0

Không thể tắt «PRIMARY KEY'. Hoặc, nếu bạn có thể, "sửa chữa" sẽ tốn một thời gian dài khủng khiếp. –

Trả lời

2

Luôn luôn khó để biết nguyên nhân của vấn đề hiệu suất là 2 xu của tôi: Khóa của bạn là uuid được phân phối ngẫu nhiên khiến khó duy trì chỉ mục. Lý do là các khóa được lưu trữ bởi phạm vi trong một khối hệ thống tập tin, do đó, có uuids ngẫu nhiên theo nhau làm cho hệ điều hành đọc và viết khối vào hệ thống tập tin mà không tận dụng bộ nhớ cache. Tôi không biết nếu bạn có thể thay đổi chìa khóa, nhưng bạn có thể có thể sắp xếp các uuids trong tập tin đầu vào và xem nếu điều đó giúp. FYI, để hiểu vấn đề này tốt hơn, tôi sẽ xem xét điều này blog post và có thể đọc cuốn sách này mysql high performance nó có một chương tốt đẹp về chỉ số cụm innodb. Chúc may mắn!

+0

có vẻ như khóa chính UUID dựa trên đã gây ra hầu hết các sự cố - thay đổi nó trong tệp dữ liệu thành một chuỗi chỉ định chuỗi đã sắp xếp cho tốc độ khoảng 6. – Michael

+0

'innodb_buffer_pool_size = 5G' cũng sẽ hữu ích. –

+0

Thảo luận thêm về [_các tệ nạn lập chỉ mục UUIDs_] (https://mariadb.com/kb/en/guiduuid-performance/). Và nó bao gồm một cách giải quyết _if_ chúng là "loại 1". –

7

Nếu bạn biết dữ liệu là "sạch", sau đó bạn có thể thả chỉ mục trên các bảng bị ảnh hưởng trước khi nhập và sau đó thêm lại chúng sau khi hoàn tất.

Nếu không, mỗi bản ghi sẽ làm giảm chỉ mục và nếu bạn có một loạt các chỉ mục, điều này có thể REALLY những thứ chậm lại.

+0

Trong trường hợp này, nó sẽ không giúp đỡ vì chỉ mục vi phạm là khóa chính. Đối với innodb khóa chính được thực hiện như là chỉ mục nhóm mà lưu trữ dữ liệu và chỉ mục khóa chính trong cùng một cấu trúc. –

+0

Vì OP không chỉ ra, và thường là một ý tưởng tốt để có chỉ mục thay thế trên bất kỳ bảng nào lưu trữ thông tin không tầm thường (và rất nhiều thông tin), tôi giả định rằng có các chỉ mục khác hiện có. Việc giảm các chỉ mục bổ sung đó _will_ giúp tốc độ chèn, vì nó sẽ cần phải thực hiện các phép tính _fewer_. Tôi đồng ý rằng chỉ mục của khóa chính cũng có khả năng gây ra sự cố, nhưng việc xóa các chỉ mục sẽ vẫn tăng tốc độ chèn. – cdeszaq

+0

Tôi đoán bạn đúng nếu có các chỉ mục khác có liên quan. –

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