提高sqlite查询速度
Improve sqlite query speed
我有一个要在数据库中更新的数字列表(实际上是百分比)。查询非常简单,我在代码中的某处获取项目的 ID,然后,我使用数字列表更新数据库中的这些项目。看我的代码:
start_time = datetime.datetime.now()
query = QtSql.QSqlQuery("files.sqlite")
for id_bdd, percentage in zip(list_id, list_percentages):
request = "UPDATE papers SET percentage_match = ? WHERE id = ?"
params = (percentage, id_bdd)
query.prepare(request)
for value in params:
query.addBindValue(value)
query.exec_()
elsapsed_time = datetime.datetime.now() - start_time
print(elsapsed_time.total_seconds())
生成list_percentages需要1秒,将所有百分比写入数据库需要2分多钟。
我使用sqlite作为数据库,数据库中大约有7000条。查询花费这么多时间是否正常?
如果不行,有什么办法可以优化吗?
编辑:
与std库中的sqlite3模块比较:
bdd = sqlite3.connect("test.sqlite")
bdd.row_factory = sqlite3.Row
c = bdd.cursor()
request = "UPDATE papers SET percentage_match = ? WHERE id = ?"
for id_bdd, percentage in zip(list_id, list_percentages):
params = (percentage, id_bdd)
c.execute(request, params)
bdd.commit()
c.close()
bdd.close()
我认为 QSqlQuery 在每个循环圈提交更改,而 sqlite3 模块允许在结束时同时提交所有不同的查询。
对于同一个测试数据库,QSqlQuery 耗时约 22 秒,而 "normal" 查询耗时约 0.3 秒。我不敢相信这只是一个性能问题,我一定是做错了什么。
你需要启动一个transaction
,并且commit
循环后的所有更新。
未测试但应该接近于:
start_time = datetime.datetime.now()
# Start the transaction time
QtSql.QSqlDatabase.transaction()
query = QtSql.QSqlQuery("files.sqlite")
for id_bdd, percentage in zip(list_id, list_percentages):
request = "UPDATE papers SET percentage_match = ? WHERE id = ?"
params = (percentage, id_bdd)
query.prepare(request)
for value in params:
query.addBindValue(value)
query.exec_()
# commit changues
if QtSql.QSqlDatabase.commit():
print "updates ok"
elsapsed_time = datetime.datetime.now() - start_time
print(elsapsed_time.total_seconds())
另一方面,这个问题可能是数据库性能问题,尝试在 id
字段上创建索引:https://www.sqlite.org/lang_createindex.html
您将需要直接访问数据库。
create index on papers (id);
你真的需要每次都调用 prepare 吗?对我来说,似乎请求没有改变,所以这个 "prepare" 函数可以移出循环?
我有一个要在数据库中更新的数字列表(实际上是百分比)。查询非常简单,我在代码中的某处获取项目的 ID,然后,我使用数字列表更新数据库中的这些项目。看我的代码:
start_time = datetime.datetime.now()
query = QtSql.QSqlQuery("files.sqlite")
for id_bdd, percentage in zip(list_id, list_percentages):
request = "UPDATE papers SET percentage_match = ? WHERE id = ?"
params = (percentage, id_bdd)
query.prepare(request)
for value in params:
query.addBindValue(value)
query.exec_()
elsapsed_time = datetime.datetime.now() - start_time
print(elsapsed_time.total_seconds())
生成list_percentages需要1秒,将所有百分比写入数据库需要2分多钟。 我使用sqlite作为数据库,数据库中大约有7000条。查询花费这么多时间是否正常? 如果不行,有什么办法可以优化吗?
编辑: 与std库中的sqlite3模块比较:
bdd = sqlite3.connect("test.sqlite")
bdd.row_factory = sqlite3.Row
c = bdd.cursor()
request = "UPDATE papers SET percentage_match = ? WHERE id = ?"
for id_bdd, percentage in zip(list_id, list_percentages):
params = (percentage, id_bdd)
c.execute(request, params)
bdd.commit()
c.close()
bdd.close()
我认为 QSqlQuery 在每个循环圈提交更改,而 sqlite3 模块允许在结束时同时提交所有不同的查询。
对于同一个测试数据库,QSqlQuery 耗时约 22 秒,而 "normal" 查询耗时约 0.3 秒。我不敢相信这只是一个性能问题,我一定是做错了什么。
你需要启动一个transaction
,并且commit
循环后的所有更新。
未测试但应该接近于:
start_time = datetime.datetime.now()
# Start the transaction time
QtSql.QSqlDatabase.transaction()
query = QtSql.QSqlQuery("files.sqlite")
for id_bdd, percentage in zip(list_id, list_percentages):
request = "UPDATE papers SET percentage_match = ? WHERE id = ?"
params = (percentage, id_bdd)
query.prepare(request)
for value in params:
query.addBindValue(value)
query.exec_()
# commit changues
if QtSql.QSqlDatabase.commit():
print "updates ok"
elsapsed_time = datetime.datetime.now() - start_time
print(elsapsed_time.total_seconds())
另一方面,这个问题可能是数据库性能问题,尝试在 id
字段上创建索引:https://www.sqlite.org/lang_createindex.html
您将需要直接访问数据库。
create index on papers (id);
你真的需要每次都调用 prepare 吗?对我来说,似乎请求没有改变,所以这个 "prepare" 函数可以移出循环?