我使用connect()和cursor()来使用SQLite
self.connector = sqlite3.connect(self.dbFile) self.cursor = self.connector.cursor()
关闭()停止使用它。
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
答案 0 :(得分:5)
连接相当昂贵 - 它们对应于打开文件 - 但游标不是那么多,只需要使用 [1] 。什么做成本是事务开始,特别是当有插入或更新时(或者当你创建表或索引时),即使你处于自动提交模式。这是因为数据库引擎必须在完成提交之前将数据同步到磁盘(持久性保证所需),而这在现代硬件上只是非常昂贵。 (事务开始成本是因为它们需要对DB文件进行一些锁定,这可能会产生影响。)
语句汇编也可能花费一些;尽可能重用编译语句。当然,无论如何你应该这样做。为什么?这是因为你永远不应该将用户数据放在生成的SQL中;这不仅会导致SQL注入漏洞的问题,而且还会强制数据库引擎在每次运行时重新编译语句。编译后的语句既更安全,也可能更快。
[1] 当然,使用比你需要的更多游标是愚蠢的。这只是浪费时间和精力。
答案 1 :(得分:1)
Connect是一项相对昂贵的操作。虽然与大多数数据库相比,sqlite connect非常快且轻巧。它实际上只是一个“fopen”和sqlite主表中的一些读取。
大多数查询将在内部使用游标,无论您是否要求它,它只是一个引用大行集的句柄,因此显式游标将花费您很少。为了处理大型结果集,游标实际上更有效,你可以在第一个结果行可用时立即访问它们,你一次只能在内存中拥有有限数量的行,如果你有时可以提前摆脱长查询决定答案不是你想要的。
我还要提出“准备”声明的推荐。它具有更好的安全性,并且,如果您智能地缓存查询,它可以节省sqlite不断解析同一块sql。
答案 2 :(得分:1)
Connect不仅仅是打开文件。一旦对数据库运行任何查询,它就必须解析sqlite_master表中的所有SQL。因此,连接时间在很大程度上取决于数据库的复杂性。简单的数据库可以在几毫秒内连接,但较大的数据库将需要更多。我们的时钟大约在45毫秒(超过一百张桌子,数百个触发器)。