Tại sao 'LOAD DATA INFILE' nhanh hơn các câu lệnh INSERT bình thường?


22

Tôi đã đọc một bài viết đề cập rằng chúng ta có thể đạt được 60.000 lần chèn mỗi giây bằng cách sử dụng LOAD DATA IN FILEcâu lệnh, đọc từ các tệp csv và chèn dữ liệu vào cơ sở dữ liệu.

Tại sao nó phải khác với chèn bình thường?

EDIT:
Tôi đã giảm chuyến đi khứ hồi bằng cách chỉ gọi một INSERTtuyên bố:

INSERT INTO tblname
VALUES (NULL,2,'some text here0'),(NULL,2,'some text here1')
    ,(NULL,2,'some text here2'),(NULL,2,'some text here3')
    .....,(NULL,2,'some text here3000');

Cái này thì sao?


Tôi đã viết một bài viết về Trung bình, điểm chuẩn chèn thêm so với LOAD DATA INFILE: Chèn tốc độ cao với MySQL . Điểm mấu chốt: bạn có thể đạt được 65% hiệu suất của LOAD DATA INFILEviệc sử dụng các phần chèn mở rộng. Tôi đã nhận 240.000 chèn / giây trên phần cứng hiện đại.
Benjamin

Câu trả lời:


26

LOAD DATA INFILE và INSERT mở rộng đều có những ưu điểm riêng biệt.

LOAD DATA INFILE được thiết kế để tải hàng loạt dữ liệu bảng trong một thao tác duy nhất cùng với chuông và còi để thực hiện các bài hát như:

  • Bỏ qua các dòng ban đầu
  • Bỏ qua các cột cụ thể
  • Chuyển đổi các cột cụ thể
  • Đang tải các cột cụ thể
  • Xử lý các vấn đề chính trùng lặp

Cần ít chi phí hơn để phân tích cú pháp

Mặt khác, nếu bạn chỉ nhập 100 hàng thay vì 1.000.000 hàng, thì INSERT mở rộng là hợp lý.

Lưu ý rằng mysqldump được thiết kế xung quanh các INSERT mở rộng với mục đích mang thiết kế bảng cùng với dữ liệu khi nó thực hiện việc tiêm hàng trăm hoặc hàng nghìn hàng cho mỗi INSERT. LOAD DATA INFILE luôn tạo ra một kiểu mẫu vật lý giữa lược đồ và dữ liệu.

Từ quan điểm của ứng dụng, LOAD DATA INFILE cũng không nhạy cảm hơn với thay đổi lược đồ so với các INSERT mở rộng.

Người ta có thể qua lại về cái tốt, cái xấu và cái xấu của việc sử dụng LOAD DATA INFILE. Cho dù bạn sử dụng kỹ thuật nào, bạn phải luôn đặt số lượng lớn_insert_buffer_size . Tại sao?

Theo Tài liệu MySQL trên Bulk_insert_buffer_size:

MyISAM sử dụng bộ đệm giống như cây đặc biệt để chèn số lượng lớn nhanh hơn cho CHỌN ... CHỌN, XÁC NHẬN ... GIÁ TRỊ (...), (...), ... và LOAD DATA INFILE khi thêm dữ liệu vào dữ liệu không trống những cái bàn. Biến này giới hạn kích thước của cây bộ đệm theo byte trên mỗi luồng. Đặt nó thành 0 sẽ vô hiệu hóa tối ưu hóa này. Giá trị mặc định là 8MB.

Trong nhiều năm, tôi đã thấy khách hàng sau khi khách hàng không đặt cái này và để nó ở mức 8MB. Sau đó, khi họ quyết định sử dụng LOAD DATA INFILE hoặc nhập mysqldumps, họ có thể cảm thấy có gì đó không đúng. Tôi thường khuyên bạn nên cài đặt này ở mức vừa phải 256M. Trong một số trường hợp, 512M.

Khi bạn có bộ đệm INSERT số lượng lớn đủ lớn, sử dụng một trong hai kỹ thuật sẽ được kết xuất mang tính học thuật và nắm bắt được sự lựa chọn cá nhân. Đối với các ứng dụng mà bạn số lượng lớn INSERT chỉ 100 hàng theo yêu cầu, hãy gắn với các INSERT mở rộng.

Nói một cách công bằng, việc nói LOAD DATA INFILE nhanh hơn khi các câu lệnh INSERT bình thường là loại câu lệnh được tải chủ yếu vì cấu hình không được tính đến. Ngay cả khi bạn thiết lập điểm chuẩn giữa LOAD DATA INFILE và INSERT mở rộng với số lượng lớn_insert_buffer_size thích hợp, các nano giây được lưu khi phân tích cú pháp mỗi hàng chỉ có thể mang lại kết quả danh nghĩa tốt nhất cho LOAD DATA INFILE.

Hãy tiếp tục và thêm nó vào my.cnf

[mysqld]
bulk_inset_buffer_size=256M

Bạn cũng có thể thiết lập nó chỉ cho phiên của mình trước khi khởi chạy INSERT mở rộng

SET bulk_insert_buffer_size= 1024 * 1024 * 256;

CẬP NHẬT 2012-07-19 14:58 EDT

Để giữ mọi thứ trong phối cảnh, bộ đệm chèn số lượng lớn chỉ hữu ích để tải các bảng MyISAM, không phải InnoDB. Tôi đã viết một bài đăng gần đây hơn về tải hàng loạt InnoDB: Tải Mysql từ infile bị kẹt chờ trên ổ cứng


4

Hầu hết các hệ thống quản lý cơ sở dữ liệu có một cơ sở tải số lượng lớn để tải khối lượng lớn dữ liệu một cách nhanh chóng. Một INSERTtuyên bố có một lượng đáng kể hành lý trên mỗi tuyên bố - khóa, phân định giao dịch, kiểm tra tính toàn vẹn tham chiếu, phân bổ tài nguyên, I / O phải được thực hiện trên cơ sở mỗi tuyên bố.

Các hoạt động chèn số lượng lớn hợp lý hóa quy trình để công cụ này có chi phí hoạt động trên mỗi hàng thấp hơn nhiều. Một DBMS có thể tải số lượng lớn các đơn đặt hàng dữ liệu có cường độ nhanh hơn thông qua các câu lệnh chèn.


3

Phân tích cú pháp và thực thi các INSERTcâu lệnh riêng lẻ mang một chi phí lớn hơn nhiều so với việc chia tệp CSV thành các cột và tải trực tiếp chúng.

Mỗi INSERTcâu lệnh phải được phân tích cú pháp riêng bởi công cụ MySQL và được kiểm tra tính hợp lệ - việc này tiêu tốn thêm tài nguyên CPU và cũng yêu cầu nhiều máy khách hơn <> máy chủ khứ hồi. Điều này không cần phải xảy ra khi tải số lượng lớn qua LOAD DATA INFILE. Cũng có những tối ưu hóa có thể diễn ra khi sử dụng LOAD DATA INFILEđể tải vào một bảng trống. Xem liên kết này để biết thêm thông tin.


xem phần EDIT trong câu hỏi của tôi
ALH

Lưu ý rằng không có phân tích cú pháp khi sử dụng các câu lệnh được chuẩn bị.
Benjamin
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.