2010-09-29 47 views
7

Tôi có một tệp db sqlite byte 100 mega mà tôi muốn tải vào bộ nhớ trước khi thực hiện truy vấn sql. Có thể làm điều đó trong python?Trong python, làm thế nào tôi có thể tải một db sqlite hoàn toàn vào bộ nhớ trước khi kết nối với nó?

Cảm ơn

+3

Đó là những gì xảy ra trước khi quá dài - tất cả đều có trong bộ nhớ. Cách duy nhất để có cơ sở dữ liệu "tất cả trong bộ nhớ" là mở một cơ sở dữ liệu có tên ": memory:" tạo và tải các bảng từ các nguồn bên ngoài. Bạn đang cố giải quyết vấn đề gì? Nó có quá chậm không? Làm thế nào để bạn biết đó là cơ sở dữ liệu chứ không phải mã của bạn? –

+0

Làm cách nào để tải các bảng từ một db ngoài vào bộ nhớ db? – relima

Trả lời

11

apsw là một wrapper thay thế cho sqlite, cho phép bạn sao lưu cơ sở dữ liệu trên đĩa vào bộ nhớ trước khi thực hiện các thao tác.

Từ docs:

### 
### Backup to memory 
### 

# We will copy the disk database into a memory database 

memcon=apsw.Connection(":memory:") 

# Copy into memory 
with memcon.backup("main", connection, "main") as backup: 
    backup.step() # copy whole database in one go 

# There will be no disk accesses for this query 
for row in memcon.cursor().execute("select * from s"): 
    pass 

connection trên là bạn db trên đĩa.

+0

Tôi thích giải pháp của bạn nhưng chỉ có một vấn đề, tôi sử dụng rất nhiều tính năng row_factory của pysqlite; và có vẻ như apsw không có tính năng này. – relima

+0

Điều này thực sự đã giải quyết được vấn đề của tôi. Truy vấn của tôi nhanh hơn MUCH. – relima

+0

nhập apsw mem_db_loader = apsw.Connection (file_sqlite_db) kết nối = apsw.Connection (": memory:") connection.backup ("main", mem_db_loader, "main").bước() cursor = connection.cursor() – relima

2
  1. Nhận một cơ sở dữ liệu trong bộ nhớ chạy (công cụ tiêu chuẩn)
  2. Attach cơ sở dữ liệu đĩa (file).
  3. Tạo lại bảng/chỉ mục và sao chép nội dung.
  4. Tháo cơ sở dữ liệu đĩa (file)

Dưới đây là một ví dụ (lấy from here) trong Tcl (có thể là hữu ích để nhận được ý tưởng chung cùng):

proc loadDB {dbhandle filename} { 

    if {$filename != ""} { 
     #attach persistent DB to target DB 
     $dbhandle eval "ATTACH DATABASE '$filename' AS loadfrom" 
     #copy each table to the target DB 
     foreach {tablename} [$dbhandle eval "SELECT name FROM loadfrom.sqlite_master WHERE type = 'table'"] { 
      $dbhandle eval "CREATE TABLE '$tablename' AS SELECT * FROM loadfrom.'$tablename'" 
     } 
     #create indizes in loaded table 
     foreach {sql_exp} [$dbhandle eval "SELECT sql FROM loadfrom.sqlite_master WHERE type = 'index'"] { 
      $dbhandle eval $sql_exp 
     } 
     #detach the source DB 
     $dbhandle eval {DETACH loadfrom} 
    } 
} 
1

Lưu ý rằng bạn có thể không cần tải một cách rõ ràng cơ sở dữ liệu vào bộ nhớ của SQLite. Đơn giản chỉ cần đệm bộ nhớ cache của hệ điều hành của bạn bằng cách sao chép nó vào null.

Windows: copy file.db nul: 
Unix/Mac: cp file.db /dev/null 

Điều này có lợi thế là hệ điều hành quản lý bộ nhớ, đặc biệt loại bỏ nó nếu có điều gì quan trọng hơn.

+0

Nó có thể chỉ là máy tính của tôi, nhưng kỹ thuật này đã không thực sự cải thiện hiệu suất của tôi. (Win 7 x64, 8gb ram). – relima

+0

Nó đã làm việc cho nhiều người khác trong danh sách gửi thư SQLite trong quá khứ, đặc biệt là sau khi một máy đã khởi động khi nó chiếm tỷ lệ bộ đệm hệ thống tệp. Trong trường hợp của bạn, rất có thể tệp đó không kết thúc trong bộ nhớ cache của tệp hệ thống. (Một số công cụ sao chép yêu cầu hệ điều hành bỏ qua bộ đệm để chúng không vứt bỏ nội dung "tốt" hiện có.) –

+1

Bí quyết "nul:" không hoạt động đối với tôi trên Win7, nhưng là bản sao thực (để temp.db). Đó là một chút bực mình b/c Tôi phải xóa các tập tin tạm thời để ngăn không gian quá nhiều trên HD, nhưng nó được tập tin vào bộ nhớ cache đĩa (làm cho truy vấn đầu tiên nhanh như các truy vấn tiếp theo). –

1

Nếu bạn đang sử dụng Linux, bạn có thể thử tmpfs là hệ thống tệp dựa trên bộ nhớ.

Nó rất dễ dàng để sử dụng nó:

  1. gắn tmpfs vào một thư mục.
  2. sao chép tệp sqlite db vào thư mục.
  3. mở tệp dưới dạng tệp sqlite db bình thường.

Hãy nhớ rằng, mọi thứ trong tmpfs sẽ bị mất sau khi khởi động lại. Vì vậy, bạn có thể sao chép tập tin db trở lại đĩa nếu nó thay đổi.

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