InnoDB chèn nhanh hơn


8

Tôi là một sinh viên tốt nghiệp nghiên cứu OLAP với Mondrian OLAP. Vì vậy, tôi muốn chèn dữ liệu vào InnoDB (MySQL 5.5) nhanh hơn khi tải ban đầu. Trong môi trường này, người dùng duy nhất là tôi, vì vậy tôi nghĩ có thể cho phép nhiều cài đặt lỏng hơn cho tốc độ chèn. Hiện tại, tôi đang sử dụng các kỹ thuật sau.

  • vô hiệu hóa log_bin
  • cho phép skip-innodb-doublewrite
  • đặt transaction_isolationthành READ-COMMITTEDhoặc READ-UNCOMMITTED(thực tế READ-COMMITED)
  • đặt innodb_flush_log_at_trx_committhành 0hoặc 2(thực tế 0)
  • đặt innodb_buffer_pool_sizethành 5GB (hệ thống có 6GB RAM)

Có thêm kỹ thuật nào để chèn nhanh hơn trên InnoDB không? Và tôi có phải sửa đổi innodb_io_read_threadinnodb_io_write_thread? Nếu bạn cần thêm thông tin, xin vui lòng cho tôi biết.

Câu trả lời:


9

BỀN VỮNG # 1

Nếu máy của bạn có nhiều lõi, bạn cần tăng các mục sau:

[mysqld]
innodb_read_io_threads = 64
innodb_write_io_threads = 64
innodb_io_capacity = 5000

Cái gì đây?

  • innodb_read_io_threads - Số lượng luồng I / O cho các hoạt động đọc trong InnoDB.
  • innodb_write_io_threads - Số lượng chủ đề I / O cho các hoạt động ghi trong InnoDB.
  • innodb_io_capacity - Giới hạn trên của hoạt động I / O được thực hiện bởi các tác vụ nền của InnoDB, chẳng hạn như xóa các trang từ nhóm bộ đệm và hợp nhất dữ liệu từ bộ đệm chèn.

BỀN VỮNG # 2

Để có dữ liệu và chỉ mục riêng biệt từ không gian bảng hệ thống (ibdata1), bạn cần thực hiện tái cấu trúc hoàn toàn InnoDB. Nghe có vẻ phức tạp, nhưng rất đơn giản. Tôi đã viết về điều này trong DBA StackExchange (ngày 29 tháng 8 năm 2012) và trong StackOverflow (ngày 29 tháng 10 năm 2010) . Các bước cơ bản là

  • Chạy SET GLOBAL innodb_fast_shutdown = 0;
  • mysqldump tất cả dữ liệu vào một bãi chứa SQL
  • service mysql stop
  • Xóa các tập tin sau
    • ibdata1
    • ib_logfile0
    • ib_logfile1
  • service mysql start

Trước khi bạn chạy service mysql start, thêm dòng này vàomy.cnf

innodb_open_files=32768

Bằng cách đó, sẽ có các tệp xử lý dành riêng cho từng bảng riêng lẻ. Mặc định là 300. Xử lý tệp đã được biết để được lưu trữ. Sẽ có một sự chậm lại nếu bạn đặt mức này rất cao và nhanh chóng chạm trần . Điều này không nên xảy ra nếu bạn đang làm việc với một số lượng nhỏ các bảng.


Cám ơn bạn đã đóng góp ý kiến. Tôi sẽ cố gắng gợi ý # 2 ngay bây giờ, và tôi sẽ điều chỉnh innodb_read_io_threads, innodb_write_io_threads, và `innodb_io_capacity'.
inohiro

"Xóa các tệp sau ibdata1" Sheesh, không có cảnh báo.
magallanes

6

Có toàn bộ tài liệu dành riêng để tải dữ liệu số lượng lớn vào InnoDB. Những ý chính:

  1. vô hiệu hóa autocommit để tránh xóa nhật ký bổ sung cho mỗi câu lệnh chèn: SET autocommit=0;...sql import;COMMIT;
  2. vô hiệu hóa kiểm tra nước ngoài và duy nhất (bạn không thể vô hiệu hóa hoàn toàn tất cả các chỉ mục):

    SET unique_checks=0;
    SET foreign_key_checks=0;
  3. Có khả năng đặt innodb_autoinc_lock_mode thành 2, thay vì 1 (mặc định). Đây là tài liệu về cài đặt này.

Thứ ba có thể hoặc không thể giúp bạn, vì vậy tôi khuyên bạn nên đọc liên kết đó để xem ban đầu bạn đang tải dữ liệu như thế nào. Chẳng hạn, nếu bạn chia tải thành nhiều lần chèn để chạy đồng thời, chắc chắn nó sẽ giúp bạn đặt giá trị thành 2. Nếu bạn đang thực hiện một thao tác chèn nhiều dòng lớn, nó sẽ không làm được gì nhiều (nếu có) Cứu giúp.

Vì bạn đang chuyển nhật ký nhị phân cho lần chèn ban đầu này, bạn không nên quan tâm đến các khoảng trống trong các số tự động (nếu thực hiện chèn đồng thời).


Cảm ơn bạn vì câu trả lời! Chèn số lượng lớn trông rất nhanh và tôi sẽ thử sau.
inohiro

Chỉ cần đặt autocommit = 0 tăng mặc dù - đặt theo đơn đặt hàng cường độ. Cảm ơn!
Alex Barker

1

Bạn có thể sử dụng các phương pháp sau để tăng tốc độ chèn:

  • Nếu bạn đang chèn nhiều hàng từ cùng một máy khách cùng một lúc, hãy sử dụng các INSERTcâu lệnh có nhiều VALUESdanh sách để chèn nhiều hàng cùng một lúc. Điều này nhanh hơn đáng kể (trong nhiều trường hợp nhanh hơn nhiều lần) so với sử dụng các INSERTcâu lệnh một hàng riêng biệt . Nếu bạn đang thêm dữ liệu vào một bảng không trống, bạn có thể điều chỉnh biến Bulk_insert_buffer_size để chèn dữ liệu nhanh hơn.
  • Khi tải một bảng từ một tệp văn bản, sử dụng LOAD DATA INFILE. Điều này thường nhanh hơn 20 lần so với sử dụng INSERTbáo cáo. Xem
  • Tận dụng thực tế là các cột có giá trị mặc định. Chèn giá trị rõ ràng chỉ khi giá trị được chèn khác với mặc định. Điều này làm giảm phân tích cú pháp mà MySQL phải làm và cải thiện tốc độ chèn.
  • Xem Phần 9.5.5, Tải dữ liệu hàng loạt cho các bảng InnoDB để biết các mẹo cụ thể cho các bảng InnoDB.

0

Kế hoạch A: "Batch" INSERT - nhiều hàng trên mỗi câu lệnh INSERT. Đề xuất khoảng 1000 hàng cho mỗi tuyên bố. autocommit = on, không rõ ràng BEGIN ... CAM KẾT

Kế hoạch B: SỐ LIỆU

Nếu bạn chèn quá nhiều hàng cùng một lúc, InnoDB phải thực hiện nhiều công việc hơn để có thể khôi phục lại phần chèn nếu có sự cố. Vì lý do này, tôi không đồng ý với autocommit = off, điều này sẽ đặt toàn bộ tập hợp vào một giao dịch.

LOAD DATA của toàn bộ các hàng có thể có cùng một vấn đề, nhưng nó khá nhanh.

buffer_pool = 5G trong số 6G đang trên bờ vực quá lớn. Nếu có bất kỳ sự hoán đổi nào, hiệu suất sẽ giảm mạnh.

THAM GIA có lẽ sẽ làm cho nó đi chậm hơn.

HIỂN THỊ TẠO BẢNG - Các khóa phụ có thể là một khuyết tật nghiêm trọng.

Bạn đang sử dụng InnoDB? hay XtraDB?


Cảm ơn bạn vì câu trả lời. Tôi đang sử dụng InnoDB. Tôi thích Kế hoạch A hơn Kế hoạch B. LOAD DATAtrông rất nhanh, nhưng chúng ta cần ghi dữ liệu vào văn bản cùng một lúc dưới dạng CSV, sau đó sử dụng LOAD DATAphải không? / Tôi sẽ đặt thành buffer_pool_size4GB.
inohiro
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.