2012-11-15 40 views
5

Tôi có một ứng dụng chạy trên Linux được nhúng. Tôi có một DB được xây dựng sẵn với một số bảng, mỗi bảng có rất nhiều hàng (hàng nghìn) và 52 cột. Tôi đã xây dựng DB phía trước, bởi vì tôi lo ngại rằng nếu tôi sẽ làm 'INSERT' tại thời gian chạy, tôi sẽ tạo ra phân mảnh đĩa, vì vậy thay vào đó tôi xây dựng một DB đầu tiên với rất nhiều rác 'INSERT' và trong thời gian chạy tôi sử dụng 'UPDATE's.Cải thiện hiệu suất của SQLite WAL

Tôi đang viết nhiều dữ liệu cho DB cứ 3 giây một lần, và đối với quy trình viết nhanh, tôi sử dụng chế độ WAL trong SQLite. Mặc dù, tôi có một vấn đề về hiệu suất. Dường như bất cứ khi nào một trạm kiểm soát xảy ra, Mất quá nhiều thời gian và bộ vi xử lý không thể thực hiện việc này trong vòng chưa đến 3 giây. Để cải thiện điều này, tôi đã tạo một chuỗi mà sau 10 cuộc gọi viết, nó nhận được một chuỗi tin nhắn từ chuỗi chính và kiểm tra điểm.

Vì vậy, bây giờ, có vẻ như tình hình tốt hơn nhưng tệp WAL ngày càng trở nên lớn hơn ... Làm cách nào tôi có thể làm việc ở đây?

Trả lời

5

Để tránh phân mảnh và loại bỏ nhu cầu chèn trước dữ liệu, bạn nên sử dụng sqlite3_file_control() với SQLITE_FCNTL_CHUNK_SIZE để đặt kích thước đoạn. Phân bổ không gian tệp cơ sở dữ liệu theo khối lớn (nói 1MB mỗi lần), nên giảm phân mảnh hệ thống tệp và cải thiện hiệu suất. Dự án Mozilla là currently using this setting trong Firefox/Thunderbird với great success.

Giới thiệu về WAL. Nếu bạn thường xuyên viết rất nhiều dữ liệu, bạn nên cân nhắc việc viết các bài viết của mình vào các giao dịch lớn hơn. Thông thường, mọi INSERT đều tự động cam kết và SQLite phải đợi cho đến khi dữ liệu thực sự được flush vào đĩa hoặc flash - điều này rõ ràng là rất chậm. Nếu bạn quấn nhiều ghi vào một giao dịch, SQLite không cần phải lo lắng về mọi hàng đơn lẻ, và có thể tuôn ra nhiều hàng cùng một lúc, rất có thể là viết một flash - nhanh hơn nhiều. Vì vậy, nếu bạn có thể, cố gắng quấn ít nhất vài trăm ghi vào một giao dịch.

Theo kinh nghiệm của tôi, WAL trên flash không thực sự hoạt động tốt và tôi thấy nó có lợi hơn khi dính vào chế độ journalling cũ. Ví dụ, Android 4 không sử dụng chế độ WAL cho cơ sở dữ liệu SQLite của nó, và có lẽ vì một lý do. Như bạn đã nhận thấy, WAL có xu hướng phát triển mà không bị ràng buộc trong một số tình huống (tuy nhiên, nó cũng sẽ xảy ra nếu giao dịch hiếm khi được cam kết - vì vậy hãy chắc chắn làm điều đó một lần trong một thời gian).

+1

Lưu ý rằng điều này ảnh hưởng đến phân bổ không gian tệp cho tệp cơ sở dữ liệu. Từ những gì tôi hiểu việc phân bổ cho tệp WAL không tôn trọng kích thước đoạn. –

1

Trong chế độ WAL, SQLite ghi bất kỳ trang nào đã thay đổi vào tệp -wal. Chỉ trong một trạm kiểm soát là những trang này được ghi lại vào tệp cơ sở dữ liệu.

Tệp -wal chỉ có thể bị cắt bớt nếu không có bất kỳ người đọc đồng thời nào.

Bạn có thể cố gắng xóa sạch tệp WAL một cách rõ ràng bằng cách gọi sqlite3_wal_checkpoint_v2 với SQLITE_CHECKPOINT_RESTART hoặc thực hiện PRAGMA wal_checkpoint(RESTART), nhưng điều này sẽ không thành công nếu có bất kỳ người đọc đồng thời nào.

+0

Điều đó dường như không trả lời được câu hỏi của tôi .. –

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