代码之家  ›  专栏  ›  技术社区  ›  prosseek

sqlite3.connect和close在sqlite中有多贵?

  •  3
  • prosseek  · 技术社区  · 14 年前

    我使用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
    
    3 回复  |  直到 14 年前
        1
  •  5
  •   Donal Fellows    14 年前

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

    语句的编译也会花费一点钱;如果可能,可以重用已编译的语句。当然,你无论如何都应该这样做。为什么?这是因为您不应该将用户数据放入生成的SQL中;这不仅会导致SQL注入漏洞的问题,而且还会强制DB引擎在每次运行该语句时重新编译该语句。编译语句是 二者都 更安全,也可能更快。


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

        2
  •  1
  •   James Anderson    14 年前

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

    大多数查询都会在内部使用一个光标,无论您是否需要它,它只是一个引用一个大行集的句柄,所以显式光标的开销非常小。对于处理大型结果集,光标实际上更高效,您可以在第一个结果行可用时立即访问它们,一次只有有限数量的行在内存中,如果确定答案不是您想要的,则可以提前退出长查询。

    我也赞成“准备好的”陈述的建议。它的安全性更好,而且,如果您智能地缓存查询,它可以避免SQLite不断解析同一块SQL。

        3
  •  1
  •   Samuel Neff    14 年前

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