2013-08-03 29 views
7

Tôi đang làm việc trên một cơ sở dữ liệu MySQL lớn và tôi cần cải thiện hiệu suất INSERT trên một bảng cụ thể. Cái này chứa khoảng 200 Hàng triệu hàng và cấu trúc của nó như sau:Cách cải thiện hiệu suất INSERT trên bảng MySQL rất lớn

(một tiền đề nhỏ: Tôi không phải là chuyên gia về cơ sở dữ liệu, vì vậy mã tôi viết có thể dựa trên cơ sở sai. Vui lòng giúp tôi hiểu sai lầm :))

CREATE TABLE IF NOT EXISTS items (
    id INT NOT NULL AUTO_INCREMENT, 
    name VARCHAR(200) NOT NULL, 
    key VARCHAR(10) NOT NULL, 
    busy TINYINT(1) NOT NULL DEFAULT 1, 
    created_at DATETIME NOT NULL, 
    updated_at DATETIME NOT NULL, 

    PRIMARY KEY (id, name), 
    UNIQUE KEY name_key_unique_key (name, key), 
    INDEX name_index (name) 
) ENGINE=MyISAM 
PARTITION BY LINEAR KEY(name) 
PARTITIONS 25; 

mỗi ngày tôi nhận được nhiều file csv trong đó mỗi dòng được sáng tác bởi các cặp "tên; then chốt", vì vậy tôi phải phân tích những tập tin này (thêm giá trị created_at và updated_at cho mỗi hàng) và chèn các giá trị vào bảng của tôi. Trong thế này, sự kết hợp của "tên" và "chìa khóa" phải là duy nhất, vì vậy tôi thực hiện các thủ tục chèn như sau:

CREATE TEMPORARY TABLE temp_items (
    id INT NOT NULL AUTO_INCREMENT, 
    name VARCHAR(200) NOT NULL, 
    key VARCHAR(10) NOT NULL, 
    busy TINYINT(1) NOT NULL DEFAULT 1, 
    created_at DATETIME NOT NULL, 
    updated_at DATETIME NOT NULL, 
    PRIMARY KEY (id) 
    ) 
ENGINE=MyISAM; 

LOAD DATA LOCAL INFILE 'file_to_process.csv' 
INTO TABLE temp_items 
FIELDS TERMINATED BY ',' 
OPTIONALLY ENCLOSED BY '\"' 
(name, key, created_at, updated_at); 

INSERT INTO items (name, key, busy, created_at, updated_at) 
(
    SELECT temp_items.name, temp_items.key, temp_items.busy, temp_items.created_at, temp_items.updated_at 
    FROM temp_items 
) 
ON DUPLICATE KEY UPDATE busy=1, updated_at=NOW(); 

DROP TEMPORARY TABLE temp_items; 

Mã chỉ được hiển thị cho phép tôi để đạt được mục tiêu của tôi, nhưng, để hoàn thành việc thực hiện , nó sử dụng khoảng 48 giờ, và đây là một vấn đề. Tôi nghĩ rằng hiệu suất kém này là do thực tế là kịch bản phải kiểm tra trên một bảng rất lớn (200 Hàng triệu) và cho mỗi chèn rằng cặp "tên, khóa" là duy nhất.

Làm cách nào để cải thiện hiệu suất của tập lệnh?

Nhờ tất cả trước.

Trả lời

2

Khóa tuyến tính của bạn trên tên và chỉ mục lớn làm chậm mọi thứ.

KEYAR KEY cần được tính toán mỗi lần chèn. http://dev.mysql.com/doc/refman/5.1/en/partitioning-linear-hash.html

bạn có thể hiển thị cho chúng tôi một số dữ liệu ví dụ về file_to_process.csv có thể nên xây dựng giản đồ tốt hơn.

Sửa nhìn kĩ hơn

INSERT INTO items (name, key, busy, created_at, updated_at) 
(
    SELECT temp_items.name, temp_items.key, temp_items.busy, temp_items.created_at, temp_items.updated_at 
    FROM temp_items 
) 

này sẽ proberly sẽ tạo ra một bảng đĩa tạm thời, điều này rất rất chậm, do đó bạn không nên sử dụng nó để có được hiệu suất hơn hoặc có thể bạn nên kiểm tra một số cài đặt mysql cấu hình như tmp-table-size và kích thước bảng tối đa có thể được định cấu hình sai.

-2

Bạn có thể sử dụng

load data local infile '' 
REPLACE 
into table 

vv ...

Các REPLACE đảm bảo rằng bất kỳ giá trị trùng lặp được ghi đè bằng các giá trị mới. Thêm SET updated_at=now() vào cuối và bạn đã hoàn tất.

Không cần bàn tạm thời.

1

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

  1. Nếu bạn đang chèn nhiều hàng từ cùng một khách hàng đồng thời, báo cáo sử dụng INSERT với nhiều giá trị liệt kê để chèn nhiều hàng tại một thời gian. Điều này nhanh hơn nhiều (nhanh hơn nhiều lần trong một số trường hợp) so với việc sử dụng các câu lệnh INSERT 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 rỗng, bạn có thể điều chỉnh biến bulk_insert_buffer_size để làm cho việc chèn dữ liệu nhanh hơn.

  2. Khi tải bảng từ tệp văn bản, hãy sử dụng LOAD DATA INFILE. Điều này thường nhanh hơn 20 lần so với việc sử dụng các câu lệnh INSERT.

  3. Tận dụng lợi thế của thực tế là các cột có giá trị mặc định. Chỉ chèn giá trị khi giá trị được chèn khác với giá trị 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.

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