Mysql
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> Mysql

Cách hiệu quả để chèn khung dữ liệu từ R sang SQL

TL; DR: LOAD DATA INFILE nhanh hơn một bậc của cường độ so với nhiều INSERT các câu lệnh, bản thân chúng nhanh hơn một bậc so với INSERT đơn lẻ tuyên bố.

Tôi đánh giá điểm chuẩn bên dưới ba chiến lược chính để nhập dữ liệu từ R vào Mysql:

  1. chèn insert tuyên bố , như trong câu hỏi:

    INSERT INTO test (col1,col2,col3) VALUES (1,2,3)

  2. nhiều insert tuyên bố , được định dạng như vậy:

    INSERT INTO test (col1,col2,col3) VALUES (1,2,3),(4,5,6),(7,8,9)

  3. load data infile tuyên bố , tức là tải tệp CSV đã viết trước đó trong mysql :

    LOAD DATA INFILE 'the_dump.csv' INTO TABLE test

Tôi sử dụng RMySQL ở đây, nhưng bất kỳ trình điều khiển mysql nào khác sẽ dẫn đến kết quả tương tự. Bảng SQL được khởi tạo bằng:

CREATE TABLE `test` (
  `col1` double, `col2` double, `col3` double, `col4` double, `col5` double
) ENGINE=MyISAM;

Kết nối và dữ liệu kiểm tra đã được tạo trong R với:

library(RMySQL)
con = dbConnect(MySQL(),
                user = 'the_user',
                password = 'the_password',
                host = '127.0.0.1',
                dbname='test')

n_rows = 1000000 # number of tuples
n_cols = 5 # number of fields
dump = matrix(runif(n_rows*n_cols), ncol=n_cols, nrow=n_rows)
colnames(dump) = paste0('col',1:n_cols)

Chèn điểm chuẩn insert tuyên bố:

before = Sys.time()
for (i in 1:nrow(dump)) {
  query = paste0('INSERT INTO test (',paste0(colnames(dump),collapse = ','),') VALUES (',paste0(dump[i,],collapse = ','),');')
  dbExecute(con, query)
}
time_naive = Sys.time() - before 

=> quá trình này mất khoảng 4 phút trên máy tính của tôi

Chèn nhiều điểm chuẩn insert tuyên bố:

before = Sys.time()
chunksize = 10000 # arbitrary chunk size
for (i in 1:ceiling(nrow(dump)/chunksize)) {
  query = paste0('INSERT INTO test (',paste0(colnames(dump),collapse = ','),') VALUES ')
  vals = NULL
  for (j in 1:chunksize) {
    k = (i-1)*chunksize+j
    if (k <= nrow(dump)) {
      vals[j] = paste0('(', paste0(dump[k,],collapse = ','), ')')
    }
  }
  query = paste0(query, paste0(vals,collapse=','))
  dbExecute(con, query)
}
time_chunked = Sys.time() - before 

=> quá trình này mất khoảng 40 giây trên máy tính của tôi

Đo điểm chuẩn load data infile tuyên bố :

before = Sys.time()
write.table(dump, 'the_dump.csv',
          row.names = F, col.names=F, sep='\t')
query = "LOAD DATA INFILE 'the_dump.csv' INTO TABLE test"
dbSendStatement(con, query)
time_infile = Sys.time() - before 

=> quá trình này mất khoảng 4 giây trên máy tính của tôi

Tạo truy vấn SQL của bạn để xử lý nhiều giá trị chèn là cách đơn giản nhất để cải thiện hiệu suất. Chuyển sang LOAD DATA INFILE sẽ dẫn đến kết quả tối ưu. Bạn có thể tìm thấy các mẹo về hiệu suất tốt trong trang này của tài liệu mysql .




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Phương thức không đồng bộ MySQL C # không hoạt động?

  2. Mô hình danh sách liền kề so với Mô hình tập hợp lồng nhau cho dữ liệu phân cấp MySQL?

  3. Mysql:Đặt bộ ký tự cột

  4. PHP Lỗi nghiêm trọng:Uncaught PDOException:không thể tìm thấy trình điều khiển

  5. Quyền truy cập bị từ chối đối với người dùng 'root' @ 'localhost' (sử dụng mật khẩu:Có) sau khi đặt lại mật khẩu LINUX