2010-09-29 10 views
7

Mam plik db sqite 100 mega bajtów, który chciałbym załadować do pamięci przed wykonaniem kwerend sql. Czy można to zrobić w pythonie?W python, jak mogę załadować sqlite db całkowicie do pamięci przed podłączeniem do niego?

Dzięki

+3

To, co się dzieje, zanim zbyt długo - wszystko zapada w pamięć. Jedynym sposobem na utworzenie bazy danych "w pamięci" jest otwarcie bazy danych o nazwie ": memory:" i utworzenie tabel z zewnętrznych źródeł. Jaki problem próbujesz rozwiązać? Czy to zbyt wolno? Skąd wiesz, że to baza danych, a nie twój kod? –

+0

Jak załadować tabele z zewnętrznego db do bazy pamięci? – relima

Odpowiedz

11

apsw jest alternatywną wrapper dla sqlite, który umożliwia wykonanie kopii zapasowej bazy danych na dysku w pamięci przed wykonaniem operacji.

Z 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 powyżej jest Twój db na dysku.

+0

Podoba mi się twoje rozwiązanie, ale jest tylko jeden problem, używam dużo funkcji row_factory w pysqlite; i wygląda na to, że apsw nie ma tej funkcji. – relima

+0

To naprawdę rozwiązało mój problem. Moje pytania są teraz DUŻO szybsze. – relima

+0

import apsw mem_db_loader = apsw.Connection (file_sqlite_db) connection = apsw.Connection (": memory:") connection.backup ("main", mem_db_loader, "main").step() cursor = connection.cursor() – relima

2
  1. Get bazy danych w pamięci z systemem (standard rzeczy)
  2. Attach baza danych na dysku (plik).
  3. Odtworzenie tabel/indeksów i skopiowanie zawartości.
  4. Odłącz bazę danych na dysku (plik)

Oto przykład (podjęte from here) w Tcl (może być przydatna dla uzyskania ogólnej idei wzdłuż):

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

Należy pamiętać, że może nie być konieczne jawne załadowanie bazy danych do pamięci SQLite. Po prostu wypełnij pamięć podręczną dysku systemu operacyjnego, kopiując ją do wartości null.

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

Ma to tę zaletę, że system operacyjny zajmuje się zarządzaniem pamięcią, w szczególności odrzucając ją, jeśli pojawi się coś ważniejszego.

+0

To może być tylko mój komputer, ale ta technika naprawdę nie poprawiła mojej wydajności. (Wygraj 7 ramek x 64 i 8 GB). – relima

+0

W przeszłości wiele osób pracowało na liście mailingowej SQLite, zwłaszcza po uruchomieniu komputera, ponieważ uruchamia pamięć podręczną systemu plików. W twoim przypadku najprawdopodobniej plik nie trafi do pamięci podręcznej systemu plików. (Niektóre narzędzia do kopiowania informują system operacyjny, aby pomijał pamięć podręczną, tak aby nie wyrzucały istniejącej "dobrej" zawartości.) –

+1

Sztuczka "nul:" nie działa dla mnie na Win7, ale prawdziwa kopia (do temp.db) ma. To trochę denerwujące b/c. Muszę skasować plik tymczasowy, aby zabezpieczyć się przed zbyt dużą ilością miejsca na dysku HD, ale przenosi go do pamięci podręcznej dysku (sprawia, że ​​pierwsze zapytanie jest równie szybkie jak kolejne zapytania). –

1

Jeśli używasz systemu Linux, możesz wypróbować tmpfs, który jest opartym na pamięci systemie plików.

Bardzo łatwo z niego korzystać:

  1. zamontować tmpfs do katalogu.
  2. skopiuj plik db sqlite do katalogu.
  3. Otwórz go jako normalny plik db sqlite.

Pamiętaj, że wszystko w tmpfs zostanie utracone po ponownym uruchomieniu komputera. Tak, możesz skopiować plik db z powrotem na dysk, jeśli został zmieniony.

Powiązane problemy