Python使用SQLite插入大量数据

2023-01-31 05:01:20 python 数据 插入

前言

使用python爬虫代理IP时,最先使用了sqlite作为存储ip数据库,sqlite简单、灵活、轻量、开源,和文件系统一样。而当大量插入爬取的数据时,出现了严重的耗时,查看一起资料后,发现:sqlite在每条insert都使用commit的时候,就相当于每次访问时都要打开一次文件,从而引起了大量的I/O操作,耗时严重。
下面是每次插入后,提交事务处理,每次插入的时间,单位是秒。

    def insert(self, sql, data):
        '''
        insert data to the table
        :param sql:
        :param data:
        :return:
        '''
        if sql is not None and sql != '':
            if data is not None:
                cu = self.getcursor()
                try:
                    for d in data:
                        cu.execute(sql, d)
                  # 每次都执行事务提交      self.conn.commit()
                except sqlite3.Error as why:
                    print "insert data failed:", why.args[0]
                cu.close()
        else:
            print "sql is empty or None"
0.134000062943
0.132999897003
0.236999988556
0.134000062943
0.120000123978
0.155999898911
0.131999969482
0.142000198364
0.119999885559
0.176000118256
0.124000072479
0.115999937057
0.111000061035
0.119999885559

显式使用事务的形式提交

在批量插入数据之后再进行事务提交,把大量操作的语句都保存在内存中,当提交时才全部写入数据库,此时,数据库文件也就只用打开一次,会显著的提高效率。

    def insert(self, sql, data):
        '''
        insert data to the table
        :param sql:
        :param data:
        :return:
        '''
        if sql is not None and sql != '':
            if data is not None:
                cu = self.getcursor()
                try:
                    for d in data:
                        cu.execute(sql, d)
                except sqlite3.Error as why:
                    print "insert data failed:", why.args[0]
                # 批量插入之后再执行事务提交
                self.conn.commit()
                cu.close()
        else:
            print "sql is empty or None"

每次插入20行数据的时间如下,单位秒,很明显的提高了效率

0.263999938965
0.117000102997
0.194999933243
0.263000011444
0.131000041962
0.15399980545
0.143000125885
0.12299990654
0.128000020981
0.121999979019
0.203999996185

写同步和执行准备方法

这两种方法主要参考提升SQLite数据插入效率低、速度慢的方法,

写同步

在SQLite中,数据库配置的参数都由编译指示(pragma)来实现的,而其中synchronous选项有三种可选状态,分别是full、nORMal、off。官方文档

当synchronous设置为FULL (2), SQLite数据库引擎在紧急时刻会暂停以确定数据已经写入磁盘。这使系统崩溃或电源出问题时能确保数据库在重起后不会损坏。FULL synchronous很安全但很慢。

当synchronous设置为NORMAL, SQLite数据库引擎在大部分紧急时刻会暂停,但不像FULL模式下那么频繁。 NORMAL模式下有很小的几率(但不是不存在)发生电源故障导致数据库损坏的情况。但实际上,在这种情况 下很可能你的硬盘已经不能使用,或者发生了其他的不可恢复的硬件错误。

设置为synchronous OFF (0)时,SQLite在传递数据给系统以后直接继续而不暂停。若运行SQLite的应用程序崩溃, 数据不会损伤,但在系统崩溃或写入数据时意外断电的情况下数据库可能会损坏。另一方面,在synchronous OFF时 一些操作可能会快50倍甚至更多。在SQLite 2中,缺省值为NORMAL.而在3中修改为FULL。

相关文章