【问题标题】:Improve sqlite query speed提高sqlite查询速度
【发布时间】:2015-02-13 14:17:40
【问题描述】:

我有一个要在数据库中更新的数字列表(实际上是百分比)。查询非常简单,我在代码中的某处获取项目的 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 秒,而“正常”查询大约需要 0.3 秒。我不敢相信这只是一个性能问题,我必须做错事。

【问题讨论】:

  • id 字段是否有索引?

标签: python sqlite pyqt


【解决方案1】:

你需要启动一个transactioncommit循环之后的所有更新。

未测试但应该接近:

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);

【讨论】:

  • 好的,但我不太明白它的作用。你能解释一下它将如何提高性能吗?
【解决方案2】:

你真的需要每次都调用prepare吗?对我来说,请求似乎没有改变,所以这个“准备”功能可以移出循环吗?

【讨论】:

  • 是的,我可以将 prepare 移出循环。但它似乎并没有提高性能。
  • python已经内置支持sqlite,不如试试和QSqlquery对比一下?
  • 是的,我做到了。对比是惊人的。我编辑了我的问题。我做错了什么,一定有其他方法可以做到这一点。
  • @Rififi,你能分享一下我可以查看的 sql 文件吗?
  • 我接受了答案,我只需要使用事务。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-09-27
  • 1970-01-01
  • 1970-01-01
  • 2012-03-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多