MongoDB
 sql >> Database >  >> NoSQL >> MongoDB

mongodb 4 volte più lento di sqlite, 2 volte più lento di csv?

I client MongoDB si connettono ai server in background. Se desideri confrontare gli inserti, un test più accurato sarebbe qualcosa del genere:

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()

Tieni presente che insert_many esegue una scrittura in blocco e ci sono limiti alle dimensioni della scrittura in blocco, in particolare possono esserci solo 1000 comandi per scrittura in blocco. Se stai inviando 1 milione di inserti, potresti vedere 2000 suddivisioni per scrittura di massa che coinvolgono tutte copie di dati. Prova a inserire 1000 documenti alla volta rispetto ad altre dimensioni batch.

Prova di lavoro:



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))

Risultati:

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 è circa 8 volte il tempo di sqlite.

È previsto? Forse. Il confronto tra sqlite e mongodb non rivela molto oltre al fatto che sqlite è notevolmente più veloce. Ma, naturalmente, questo è previsto poiché mongodb utilizza un'architettura client/server e sqlite è un database in-process, il che significa:

  • Il client deve serializzare i dati da inviare al server
  • Il server deve deserializzare quei dati
  • Il server deve quindi analizzare la richiesta e capire cosa fare
  • Il server ha bisogno di scrivere i dati in modo scalabile/concorrente (sqlite semplicemente errori con errori di scrittura simultanei da quello che mi ricordo)
  • Il server deve ricomporre una risposta al client, serializzare quella risposta, scriverla sulla rete
  • Il cliente deve leggere la risposta, deserializzare, verificarne l'esito positivo

Rispetto a cosa:un database in-process che non esegue nessun i/o di rete?

Le chiamate di scrittura fisica sono una piccola parte di ciò che viene inserito nell'archiviazione dei dati da un database moderno.

Inoltre, nessuno dei due casi ne coinvolge un milione. Quando scrivi su file, le scritture vengono memorizzate nel buffer dalla libreria standard di Python prima ancora di essere inviate al kernel:devi usare flush() dopo ogni riga per produrre effettivamente un milione di scritture. In un database le scritture vengono eseguite allo stesso modo pagina per pagina e non per singoli documenti.