MongoDB
 sql >> Base de Dados >  >> NoSQL >> MongoDB

mongodb 4x mais lento que o sqlite, 2x mais lento que o csv?


Os clientes MongoDB se conectam aos servidores em segundo plano. Se você quiser fazer benchmark de inserções, um teste mais preciso seria algo assim:
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()

Tenha em mente que insert_many executa uma gravação em massa e há limites nos tamanhos de gravação em massa, em particular, pode haver apenas 1.000 comandos por gravação em massa. Se você estiver enviando 1 milhão de inserções, poderá observar 2.000 divisões por gravação em massa, todas envolvendo cópias de dados. Teste a inserção de 1.000 documentos por vez em comparação com outros tamanhos de lote.

Teste de trabalho:


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 é cerca de 8x o tempo do sqlite.

Isso é esperado? Talvez. A comparação entre sqlite e mongodb não revela muito além de que sqlite é marcadamente mais rápido. Mas, naturalmente, isto é esperado, pois o mongodb utiliza uma arquitetura cliente/servidor e o sqlite é um banco de dados em processo, o que significa:
  • O cliente precisa serializar os dados para enviar ao servidor
  • O servidor precisa desserializar esses dados
  • O servidor precisa analisar a solicitação e descobrir o que fazer
  • O servidor precisa gravar os dados de maneira escalável/concorrente (o sqlite simplesmente erros com erros de gravação simultâneos do que me lembro)
  • O servidor precisa compor uma resposta para o cliente, serializar essa resposta, gravá-la na rede
  • O cliente precisa ler a resposta, desserializar e verificar se ela foi bem-sucedida

Comparado com o que - um banco de dados em processo que não faz nenhum E/S de rede?

As chamadas de gravação física são uma pequena parte do que entra no armazenamento de dados por um banco de dados moderno.

Além disso, nenhum dos casos envolve um milhão deles. Quando você escreve no arquivo, as gravações são armazenadas em buffer pela biblioteca padrão do python antes mesmo de serem enviadas para o kernel - você deve usar flush() após cada linha para produzir um milhão de gravações. Em um banco de dados, as gravações são executadas de forma semelhante em uma base de página por página e não para documentos individuais.