Klien MongoDB terhubung ke server di latar belakang. Jika Anda ingin membandingkan sisipan, tes yang lebih akurat adalah seperti ini:
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()
Ingatlah bahwa insert_many melakukan penulisan massal dan ada batasan ukuran penulisan massal, khususnya hanya ada 1000 perintah per penulisan massal. Jika Anda mengirim 1 juta sisipan, Anda bisa melihat 2000 split per penulisan massal yang semuanya melibatkan salinan data. Uji penyisipan 1000 dokumen sekaligus vs ukuran batch lainnya.
Tes kerja:
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))
Hasil:
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 sekitar 8x waktu sqlite.
Apakah ini diharapkan? Mungkin. Perbandingan antara sqlite dan mongodb tidak mengungkapkan banyak hal selain itu sqlite jauh lebih cepat. Tapi, tentu saja, ini diharapkan karena mongodb menggunakan arsitektur klien/server dan sqlite adalah database dalam proses, artinya:
- Klien harus membuat serial data untuk dikirim ke server
- Server harus melakukan deserialize data tersebut
- Server kemudian harus menguraikan permintaan dan mencari tahu apa yang harus dilakukan
- Server perlu menulis data dengan cara yang terukur/bersamaan (sqlite hanya kesalahan dengan kesalahan penulisan bersamaan dari apa yang saya ingat)
- Server perlu membuat tanggapan kembali ke klien, membuat serial tanggapan itu, menulisnya ke jaringan
- Klien perlu membaca tanggapan, membatalkan serialisasi, memeriksa keberhasilannya
Dibandingkan dengan apa - database dalam proses yang tidak melakukan apa pun jaringan i/o?
Panggilan tulis fisik adalah bagian kecil dari apa yang masuk ke penyimpanan data oleh database modern.
Selain itu, tidak ada kasus yang melibatkan satu juta dari mereka. Saat Anda menulis ke file, penulisan disangga oleh pustaka standar python bahkan sebelum dikirim ke kernel - Anda harus menggunakan flush()
setelah setiap baris untuk benar-benar menghasilkan satu juta penulisan. Dalam database, penulisan dilakukan secara serupa pada halaman demi halaman dan bukan untuk dokumen individual.