2013-08-13 30 views
13

tôi đọc này: Importing a CSV file into a sqlite3 database table using PythonBulk chèn dữ liệu khổng lồ vào SQLite sử dụng Python

và có vẻ như rằng tất cả mọi người gợi ý sử dụng line-by-line đọc thay vì sử dụng .import số lượng lớn từ SQLite. Tuy nhiên, điều đó sẽ làm cho việc chèn thực sự chậm nếu bạn có hàng triệu hàng dữ liệu. Có cách nào khác để phá vỡ điều này không?

Cập nhật: Tôi đã thử mã sau để chèn từng dòng nhưng tốc độ không tốt như tôi mong đợi. Liệu có cách nào để cải thiện nó

for logFileName in allLogFilesName: 
    logFile = codecs.open(logFileName, 'rb', encoding='utf-8') 
    for logLine in logFile: 
     logLineAsList = logLine.split('\t') 
     output.execute('''INSERT INTO log VALUES(?, ?, ?, ?)''', logLineAsList) 
    logFile.close() 
connection.commit() 
connection.close() 

Trả lời

17

Chia dữ liệu của bạn thành các khối bằng cách sử dụng biểu thức trình tạo, chèn vào bên trong giao dịch. Dưới đây là báo giá từ sqlite optimization FAQ:

Trừ khi đã có trong giao dịch, mỗi câu lệnh SQL có một giao dịch mới bắt đầu. Điều này là rất tốn kém, vì nó yêu cầu mở lại, ghi vào và đóng tệp nhật ký cho mỗi câu lệnh . Điều này có thể tránh được bằng cách gói chuỗi các câu lệnh SQL bằng BEGIN GIAO DỊCH; và END GIAO DỊCH; các câu lệnh. Điều này tăng tốc cũng thu được cho các báo cáo mà không làm thay đổi cơ sở dữ liệu.

Here's cách mã của bạn có thể trông như thế nào.

Ngoài ra, sqlite có khả năng import CSV files.

+0

SQLite có thể nhập nhiều tệp CSV cùng một lúc hay không. Tôi không thể tìm cách để làm điều đó? – Shar

+0

Đừng nghĩ rằng có thể nhập nhiều tệp csv cùng một lúc. Tách dữ liệu theo khối và chèn chúng vào các giao dịch nên là con đường để đi, tôi nghĩ vậy. – alecxe

+0

Cảm ơn bạn! Tôi nghĩ rằng tôi sẽ đi với điều đó. – Shar

14

Sqlite thể làm tens of thousands of inserts per second, chỉ cần đảm bảo để làm tất cả trong số họ trong một giao dịch duy nhất bằng cách bao quanh chen với BEGIN và COMMIT. (executemany() thực hiện điều này tự động.)

Như thường lệ, đừng tối ưu hóa trước khi bạn biết tốc độ sẽ là một vấn đề. Kiểm tra giải pháp dễ nhất trước tiên và chỉ tối ưu hóa nếu tốc độ không thể chấp nhận được.

+0

Cảm ơn! Tôi đang cố gắng ngay bây giờ và sẽ báo cáo về tốc độ. – Shar

+0

Tôi vừa thử những gì bạn đề xuất bằng cách chèn từng dòng một. Tốc độ không quá tệ, nhưng nó vẫn không nhanh như tôi mong đợi. Có lẽ mã của tôi không đủ viết. Tôi đã cập nhật nó trong câu hỏi ở trên. Bạn có đề nghị nào không? – Shar

23

Vì đây là kết quả hàng đầu trên tìm kiếm của Google, tôi nghĩ có thể tốt hơn khi cập nhật câu hỏi này.

Từ python sqlite docs bạn có thể sử dụng

import sqlite3 

persons = [ 
    ("Hugo", "Boss"), 
    ("Calvin", "Klein") 
] 

con = sqlite3.connect(":memory:") 

# Create the table 
con.execute("create table person(firstname, lastname)") 

# Fill the table 
con.executemany("insert into person(firstname, lastname) values (?,?)", persons) 

Tôi đã sử dụng phương pháp này để cam kết trên 50k chèn hàng tại một thời điểm và nó nhanh như chớp.

+1

Nó cũng nhanh như chớp vì bạn đang sử dụng sqlite làm cơ sở dữ liệu trong bộ nhớ ... – aramaki

+0

giảm tác vụ tạo 2 phút xuống dưới một giây! và đó là một cơ sở dữ liệu tập tin, vì vậy nó là sét anyway – Math

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