3

我使用 connect() 和 cursor() 来使用 SQLite

self.connector = sqlite3.connect(self.dbFile)
self.cursor = self.connector.cursor()

并 close() 停止使用它。

self.cursor.close()

它们有多贵(就处理时间而言)?它是否如此昂贵以至于只有绝对必要才需要使用它?或者,是否可以在一个函数中多次使用它?

添加

我用下面的简单代码进行了测试。proc1() 使用在运行查询时始终打开和关闭的代码,而 proc2() 只运行一次。

from sqlite import *
import timeit
import math

def proc1():
    db = SQLiteDB("./example.db", False)
    db.getOpenRunClose("SELECT * from Benchmark")
    db.getOpenRunClose("SELECT * from Benchmark")
    db.getOpenRunClose("SELECT * from Benchmark")
    db.getOpenRunClose("SELECT * from Benchmark")
    db.getOpenRunClose("SELECT * from Benchmark")
    db.getOpenRunClose("SELECT * from Benchmark")

def proc2():
    db = SQLiteDB("./example.db")
    res = db.runSQLToGetResult("SELECT * from Benchmark")
    res = db.runSQLToGetResult("SELECT * from Benchmark")
    res = db.runSQLToGetResult("SELECT * from Benchmark")
    res = db.runSQLToGetResult("SELECT * from Benchmark")
    res = db.runSQLToGetResult("SELECT * from Benchmark")
    res = db.runSQLToGetResult("SELECT * from Benchmark")
    db.close()

if __name__ == '__main__':
    t = timeit.Timer(proc1)
    count = 5000
    print t.timeit(count) / count

    t = timeit.Timer(proc2)
    count = 5000
    print t.timeit(count) / count

结果如下。

0.00157478599548
0.000539195966721
4

3 回答 3

5

连接相当昂贵——它们对应于打开文件——但游标的使用量并不像你需要的那样多[1]。即使您处于自动提交模式,成本是事务启动,尤其是在插入或更新(或者如果您创建表或索引时)特别是提交这是因为数据库引擎必须在完成提交之前将数据同步到磁盘(这是持久性保证所必需的),而这在现代硬件上非常昂贵。(事务启动成本是因为它们需要对数据库文件进行一些锁定,这可能会产生影响。)

语句的编译也可能会花费一些;如果可能,重用已编译的语句。当然,无论如何你都应该这样做。为什么?这是因为您永远不应该将用户数据放在生成的 SQL 中;这不仅会导致 SQL 注入漏洞的麻烦,而且还会迫使数据库引擎在每次运行时重新编译该语句。编译语句安全又(可能)更快。


[1]当然,使用比你需要的更多的游标是愚蠢的。那简直是在浪费时间和精力。

于 2010-09-19T20:10:25.863 回答
1

Connect 是一项相对昂贵的操作。尽管与大多数数据库相比,sqlite connect 非常快速且轻巧。它实际上只是一个“fopen”和一些从 sqlite 主表中读取的内容。

无论您是否请求,大多数查询都会在内部使用游标,它只是引用大型行集的句柄,因此显式游标将花费您很少的钱。对于处理大型结果集,游标实际上更有效,您可以在第一条结果行可用时立即访问它们,一次在内存中只有有限数量的行,如果您可以提前退出长查询决定答案不是你想要的。

我还将支持“准备好的”陈述的建议。它具有更好的安全性,并且,如果您智能地缓存查询,它可以避免 sqlite 不断解析同一段 sql。

于 2010-09-21T03:09:51.563 回答
1

Connect 不仅仅是打开一个文件。一旦您对数据库运行任何查询,它就必须解析出 sqlite_master 表中的所有 SQL。因此,连接时间在很大程度上取决于数据库的复杂性。简单的数据库可以在几毫秒内连接,但较大的数据库需要更多时间。我们的时钟在 45 毫秒左右(超过一百个表,数百个触发器)。

于 2010-09-21T03:30:15.023 回答