2011-12-12 8 views
5

Tôi có một bảng cơ sở dữ liệu như dưới đây:Làm thế nào để chèn 20 triệu bản ghi vào cơ sở dữ liệu MySql càng nhanh càng tốt

create table temperature 
(id int unsigned not null auto_increment primary key, 
temperature double 
); 

Và trong chương trình của tôi, tôi có khoảng 20 triệu nhiệt độ để chèn vào bảng. Tôi lo lắng trong môi trường .Net, sử dụng Connector/Net kết nối với MySql. Các mã được như dưới đây:

List<double> temps = new List<double>(); 
... 
string connStr = "server=localhost;user=name;database=test;port=3306;password=*****;"; 
MySqlConnection conn = new MySqlConnection(connStr); 
try 
{ 
    conn.Open(); 

    //temps.Count is about 20 million 
    for (int i = 0; i < temps.Count; i++) 
    { 
     string sql1 = "INSERT INTO temperature VALUES (null, "+temps[i]+")"; 
     MySqlCommand cmd1 = new MySqlCommand(sql1, conn); 
     cmd1.ExecuteNonQuery(); 
    } 

} 
catch (Exception ex) 
{ 
    Console.WriteLine(ex.ToString()); 
} 
conn.Close(); 

Làm thế nào tôi có thể chèn nhiều dòng dữ liệu càng nhanh càng tốt? (Nó chỉ có thể chèn 2000 bản ghi mỗi phút trong máy tính của tôi.)

+1

Tôi hơi tò mò. Tại sao bạn chèn 20 triệu nhiệt độ trong một DB? –

+0

Bạn có cần autoincrement? Tôi có một tình huống tương tự (trên máy chủ sql) và tôi quản lý các bên khách hàng gia tăng phím trên bộ nạp. Tôi mange 75.000 hàng mỗi giây trên phần cứng hiện tại của tôi. Không có SQL, mặc dù ... – TomTom

+0

Cũng sql của bạn "sucks";) bạn có thể không gửi nhiều câu lệnh chèn trong một lần chạy không? Nó là một chuỗi - mysql có thể xử lý hthat? 10 lượt đi cho mỗi chuyến đi khứ hồi là 10% các chuyến đi khứ hồi. Threads thêm moer vào đó (tải đa luồng). – TomTom

Trả lời

5

bạn có thể sử dụng khái niệm bulk insert thực hiện nhiều lần chèn cùng lúc giảm thiểu phí gọi ExecuteNonQuery nhiều lần.

trong MySQL này được gọi là LOAD DATA, đánh dấu vào đây để biết chi tiết: http://dev.mysql.com/doc/refman/5.5/en/load-data.html

trong MS SQL Server này được gọi là bulk insert và nó được gọi là như vậy, đó là lý do tại sao tôi đã đề cập đến nó với tên này.

0

Quy tắc chung: -

  1. use load data infile
  2. vô hiệu hóa chính trong lúc nhập, kích hoạt nó trở lại sau khi tất cả các dữ liệu đã được nhập khẩu
  3. chạy kịch bản tại máy chủ cơ sở dữ liệu riêng của mình, kết nối sử dụng ổ cắm thay vì tcp/ip

Hầu hết các mẹo được giải thích trong tài liệu.

+0

quy tắc chung # 2 sẽ không áp dụng ở đây vì nó là khóa tự động chính –

1

Bạn nên chèn số lượng lớn. Cách ADO.NET để làm điều đó là bằng cách sử dụng một DataAdapter.

Đối với giải pháp cụ thể của MySQL, hãy sử dụng MySqlBulkLoader.

4

Có một số cách để tối ưu hóa chèn hàng loạt. Một số là:

  • LOAD DATA INFILE. Có một số wrapper API for .NET. Đây là cách nhanh nhất, nhưng có một số hạn chế và khác biệt ngữ nghĩa từ chèn đơn giản.

  • Nhiều hàng INSERT báo cáo:

    INSERT INTO temperature (temperature) VALUES (1.0), (2.0), (3.0), ...

    Bạn không nên chèn 20.000.000 hàng cùng một lúc, nhưng có thể muốn thử 1,000-10,000 cho một rất lớn tốc độ lên. Đây là một cách đơn giản và rất không hiệu quả để tăng tốc độ. Một yếu tố của 10 và đôi khi cách nhiều hơn là thường có thể.

  • Khóa bảng (LOCK TABLES).

  • Tạm thời tắt chỉ mục.

  • Điều chỉnh tùy chọn MySQL.

  • INSERT DELAYED (rất có thể không hữu ích ở đây).

Tài liệu cung cấp cho bạn more elaborate detail về các tùy chọn. Một số tùy chọn tùy thuộc vào loại bảng (InnoDBMyISAM).

Đề xuất chung: Luôn chỉ định các cột bạn chèn trước VALUES. Điều này làm cho mã dễ bảo trì hơn.