MongoDB
 sql >> Datenbank >  >> NoSQL >> MongoDB

mongodb 4x langsamer als sqlite, 2x langsamer als csv?

MongoDB-Clients verbinden sich im Hintergrund mit den Servern. Wenn Sie Inserts vergleichen möchten, wäre ein genauerer Test ungefähr so:

with pymongo.MongoClient() as client:
  client['warmup']['warmup'].insert_many(docs)
  db = client['test']
  coll = db['test']
  start = time()
  coll.insert_many(docs)
  end = time()

Denken Sie daran, dass insert_many einen Massenschreibvorgang ausführt und es Beschränkungen für die Größe von Massenschreibvorgängen gibt, insbesondere dürfen nur 1000 Befehle pro Massenschreibvorgang vorhanden sein. Wenn Sie 1 Million Inserts senden, könnten Sie 2000 Splits pro Massenschreibvorgang sehen, die alle Datenkopien beinhalten. Testen Sie das gleichzeitige Einfügen von 1000 Dokumenten im Vergleich zu anderen Stapelgrößen.

Arbeitstest:



import csv
import sqlite3
import pymongo, random, time

N, M = 1000000, 5
docs = [{'_id':1,'b':2,'c':3,'d':4,'e':5}]*N
i=1
for i in range(len(docs)):
    docs[i]=dict(docs[i])
    docs[i]['_id'] = i
data=[tuple(doc.values())for doc in docs]

with open('test.csv', 'w', newline='') as file:
    writer = csv.writer(file, delimiter=',')
    start = time.time()
    for i in range(N):
        writer.writerow(data[i])
    end = time.time()
    print('%f' %( end-start))


con = sqlite3.connect('test.db')
con.execute('drop table if exists five')
con.execute('create table five(a, b, c, d, e)')
start = time.time()
con.executemany('insert into five(a, b, c, d, e) values (?,?,?,?,?)', data)


end = time.time()
print('%f' %( end-start))



with pymongo.MongoClient() as client:
  client['warmup']['warmup'].delete_many({})
  client['test']['test'].delete_many({})
  client['warmup']['warmup'].insert_many(docs)
  db = client['test']
  coll = db['test']
  start = time.time()
  coll.insert_many(docs)
  end = time.time()
print('%f' %( end-start))

Ergebnisse:

risque% python3 test.py
0.001464
0.002031
0.022351

risque% python3 test.py
0.013875
0.019704
0.153323

risque% python3 test.py
0.147391
0.236540
1.631367

risque% python3 test.py
1.492073
2.063393
16.289790

MongoDB benötigt etwa das 8-fache der SQLite-Zeit.

Wird dies erwartet? Vielleicht. Der Vergleich zwischen sqlite und mongodb verrät nicht viel, außer dass sqlite deutlich schneller ist. Aber natürlich das wird erwartet, da mongodb eine Client/Server-Architektur verwendet und sqlite eine In-Process-Datenbank ist, was bedeutet:

  • Der Client muss die Daten serialisieren, um sie an den Server zu senden
  • Der Server muss diese Daten deserialisieren
  • Der Server muss dann die Anfrage parsen und herausfinden, was zu tun ist
  • Der Server muss die Daten auf skalierbare/gleichzeitige Weise schreiben (sqlite einfach Fehler mit gleichzeitigen Schreibfehlern, soweit ich mich daran erinnere)
  • Der Server muss eine Antwort an den Client zusammenstellen, diese Antwort serialisieren und in das Netzwerk schreiben
  • Der Client muss die Antwort lesen, deserialisieren und auf Erfolg prüfen

Im Vergleich zu was - einer In-Process-Datenbank, die irgendwelche nicht tut Netzwerk-E/A?

Die physischen Schreibaufrufe sind ein kleiner Teil dessen, was von einer modernen Datenbank in die Datenspeicherung einfließt.

Abgesehen davon betrifft keiner der Fälle eine Million von ihnen. Wenn Sie in eine Datei schreiben, werden die Schreibvorgänge von Pythons Standardbibliothek gepuffert, bevor sie überhaupt an den Kernel gesendet werden - Sie müssen flush() verwenden nach jeder Zeile, um tatsächlich eine Million Schreibvorgänge zu produzieren. In einer Datenbank werden die Schreibvorgänge in ähnlicher Weise Seite für Seite und nicht für einzelne Dokumente ausgeführt.