Los clientes de MongoDB se conectan a los servidores en segundo plano. Si desea comparar las inserciones, una prueba más precisa sería algo como esto:
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()
Tenga en cuenta que insert_many realiza una escritura masiva y que existen límites en los tamaños de escritura masiva, en particular, solo puede haber 1000 comandos por escritura masiva. Si está enviando 1 millón de inserciones, podría estar viendo 2000 divisiones por escritura masiva que involucran copias de datos. Pruebe la inserción de 1000 documentos a la vez frente a otros tamaños de lote.
Prueba de trabajo:
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))
Resultados:
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 es aproximadamente 8 veces el tiempo de sqlite.
¿Es esto esperado? Quizás. La comparación entre sqlite y mongodb no revela mucho más que sqlite es notablemente más rápido. Pero, naturalmente, esto se espera ya que mongodb utiliza una arquitectura cliente/servidor y sqlite es una base de datos en proceso, lo que significa:
- El cliente tiene que serializar los datos para enviarlos al servidor
- El servidor tiene que deserializar esos datos
- El servidor tiene que analizar la solicitud y decidir qué hacer
- El servidor necesita escribir los datos de una manera escalable/concurrente (sqlite simplemente comete errores con errores de escritura concurrentes por lo que recuerdo)
- El servidor necesita redactar una respuesta para el cliente, serializar esa respuesta, escribirla en la red
- El cliente debe leer la respuesta, deserializarla y verificar que tenga éxito
Comparado con qué:una base de datos en proceso que no hace ninguna E/S de red?
Las llamadas de escritura física son una pequeña parte de lo que se almacena en una base de datos moderna.
Además de lo cual, ningún caso involucra a un millón de ellos. Cuando escribe en un archivo, las escrituras se almacenan en el búfer de la biblioteca estándar de python incluso antes de que se envíen al kernel; debe usar flush()
después de cada línea para producir un millón de escrituras. En una base de datos, las escrituras se realizan de manera similar página por página y no para documentos individuales.