Background
在使用sqlite數據庫時,雖然數據庫以文件形式存在,並且基本ubuntu默認安裝sqlite數據庫,使用起來非常方便。
但是由於數據庫比較簡單,操作效率比較低。
非常明顯的就是數據更新,也就是update
語句是非常非常非常慢!
(我不會告訴你我的一個百萬級的數據更新跑了3天還沒跑完。)
Method
- 關閉同步
- 顯式開啓事務
- COMMIT
代碼爲:
def fastUpdate(sql, list_datas,db):
'''
sql: sql
list_datas:data list to update or insert
db : sqlite connection
'''
db.execute("PRAGMA synchronous=OFF") #關閉同步
db.execute("BEGIN TRANSACTION") #顯式開啓事務
cur = db.cursor()
cur.executemany(sql, list_datas)
db.execute("COMMIT") #COMMIT
cur.close()
Evaluation
相比普通的更新方式,分別更新500,000條數據,記錄執行需要時間。
import sqlite3
from datetime import datetime
def fastUpdate(sql, list_datas,db):
'''
sql: sql
list_datas:data list to update or insert
db : sqlite connection
'''
db.execute("PRAGMA synchronous=OFF")
db.execute("BEGIN TRANSACTION")
cur = db.cursor()
cur.executemany(sql, list_datas)
db.execute("COMMIT")
cur.close()
def slowUpdate(sql, list_datas, db):
'''
sql: sql
list_datas:data list to update or insert
db : sqlite connection
'''
cur = db.cursor()
cur.executemany(sql, list_datas)
db.commit()
cur.close()
db = sqlite3.connect("test.sqlite")
#data generation
To_Insert_data = []
for i in range(1000000):
To_Insert_data.append((i, i+123,i))
sql = "update test set id=?,num=? where id=?"
t1 = datetime.now()
slowUpdate(sql, To_Insert_data[0:500000], db)
t2 = datetime.now()
print("Slow Op time: %s" % (t2-t1))
t3 = datetime.now()
fastUpdate(sql, To_Insert_data[500000:], db)
t4 = datetime.now()
print("Fast Op time: %s" % (t4-t3))
db.close()
執行三次,時間統計爲:
root@b26d5e2d88ae:/test# python FastInsertSqlite.py
Slow Op time: 0:00:02.372968
Fast Op time: 0:00:01.687531
root@b26d5e2d88ae:/test# python FastInsertSqlite.py
Slow Op time: 0:00:02.382283
Fast Op time: 0:00:01.508636
root@b26d5e2d88ae:/test# python FastInsertSqlite.py
Slow Op time: 0:00:02.371668
Fast Op time: 0:00:01.692238
Conclusion
使用這種方式,時間提升28.8%左右。(這麼少?)
Reference
https://stackoverflow.com/questions/17867605/performance-of-insert-with-python-and-sqlite3