Les clients MongoDB se connectent aux serveurs en arrière-plan. Si vous souhaitez comparer les inserts, un test plus précis ressemblerait à ceci :
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()
Gardez à l'esprit que insert_many effectue une écriture en masse et qu'il existe des limites sur la taille des écritures en masse, en particulier il ne peut y avoir que 1 000 commandes par écriture en masse. Si vous envoyez 1 million d'insertions, vous pourriez envisager 2 000 fractionnements par écriture en bloc, qui impliquent tous des copies de données. Testez l'insertion de 1 000 documents à la fois par rapport à d'autres tailles de lot.
Essai de fonctionnement :
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))
Résultats :
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 est environ 8 fois plus rapide que sqlite.
Est-ce prévu ? Peut-être. La comparaison entre sqlite et mongodb ne révèle pas grand-chose à part le fait que sqlite est nettement plus rapide. Mais, naturellement, ça est attendu puisque mongodb utilise une architecture client/serveur et que sqlite est une base de données en cours, ce qui signifie :
- Le client doit sérialiser les données à envoyer au serveur
- Le serveur doit désérialiser ces données
- Le serveur doit ensuite analyser la requête et déterminer quoi faire
- Le serveur doit écrire les données de manière évolutive/concurrente (sqlite simplement des erreurs avec des erreurs d'écriture simultanées d'après mes souvenirs)
- Le serveur doit composer une réponse pour le client, sérialiser cette réponse, l'écrire sur le réseau
- Le client doit lire la réponse, désérialiser, vérifier son succès
Par rapport à quoi - une base de données in-process qui ne fait rien E/S réseau ?
Les appels d'écriture physique ne représentent qu'une petite partie de ce qui entre dans le stockage de données d'une base de données moderne.
De plus, aucun des deux cas n'en implique un million. Lorsque vous écrivez dans un fichier, les écritures sont mises en mémoire tampon par la bibliothèque standard de python avant même d'être envoyées au noyau - vous devez utiliser flush()
après chaque ligne pour produire un million d'écritures. Dans une base de données, les écritures sont également effectuées page par page et non pour des documents individuels.