2016-04-04 3 views
0

Ich habe eine einfache Python-Klasse, die Unterklassen von Thread. In der run-Methode stelle ich eine Verbindung zu SQLite db her, mache eine einfache Select-Abfrage und schließe die Verbindung. Ziemlicher Standard:Python sqlite3 - Nur Lesen von mehreren Threads = SLOW

def run(self): 
    conn = sqlite3.connect(SHAPE_CACHE_DB) 
    curs = conn.cursor() 
    curs.execute('SELECT * from foo') 
    for row in curs.fetchall(): 
     # do stuff 
    curs.close() 
    conn.close() 

Wenn nur ein Thread zu einem Zeitpunkt ausgeführt wird, die run-Methode führt sehr schnell - läßt nur < 1 Sekunde. Aber wenn mehrere Instanzen der Klasse instanziiert und ausgeführt werden - sagen wir 6 oder mehr, kann die run-Methode viele Sekunden dauern ???

Ich vermute, es gibt einige Konflikte zwischen Lesezugriff zwischen den Threads. Aber ich dachte sqlite erlaubt Lesezugriff auf gleichzeitige Threads ???

Antwort

1

Zunächst wird das SQLite-Modul ist nicht THREAD:

https://docs.python.org/2/library/sqlite3.html#multithreading

Zweitens, können Sie die „SAME“ Abfrage von sechs Threads tun das heißt, Sie sechs Mal tun, wie viel Arbeit. Ein etwas fairerer Vergleich wäre, wenn Ihre Single-Thread-Version sechs Abfragen in einer Schleife ausführen würde.

Drittens, für Sie wird Thread wechseln mit mehreren Threads und zahlen einige Kosten dafür.

+0

Die SQL ändert sich tatsächlich pro Thread. Und in der Python-Dokumentverknüpfung, auf die Sie verweisen, heißt es, dass Cursor und Verbindungen nicht über Threads gemeinsam genutzt werden können. Ich mache das hier nicht - jeder Thread verwaltet seine eigene Verbindung und seinen Cursor. Also muss hier ein anderes Schloss im Spiel sein. – user163757

+0

obwohl sql ändert sich zwischen Threads - Ergebnismenge wird sehr nahe sein. – user163757

+0

Einverstanden, der erste Grund gilt sowieso nicht für die Geschwindigkeit. Es war nur ein FYI. Wenn die Größe der Ergebnismenge sehr ähnlich ist, kann dies der Grund für die größere Zeit sein. – Sid

0

Ich denke, das ist/war ein GIL-Problem. Anstatt Unterklasse Thread, wechselte ich zu Multiprocessing.Process - alle Instanzen der Klasse führen jetzt ähnlich.