哪个更好-execute(INSERT)或executemany(INSERT)

时间:2018-07-09 02:17:02

标签: python python-3.x sqlite pysqlite

情况:需要在SQLite数据库中插入大量数据。

问题:我们可以使用两个语句来插入数据-

data = [("111", "222", "333"), ("AAA", "BBB", "CCC"), ("XXX", "YYY", "ZZZ")]

#method1
for item in data:
    cursor.execute("INSERT INTO table(value1, value2, value3) VALUES (?,?,?)", item)
    conn.commit()

#method2
cursor.execute("INSERT INTO table(value1, value2, value3) VALUES(?,?,?)", data)
conn.commit()

问题:如果忽略速度,从编程的角度来看,哪种方法更好?并尽可能说明原因。

1 个答案:

答案 0 :(得分:3)

从纯编程实践的角度来看,除了速度之外,没有区别。但是...

准备好的陈述是好的。但是,mass-insert产生了大量的变量绑定,SQLite可以处理的主机参数数量为upper limit,默认值为999。

因此,多插入很适合玩玩,但对于真实数据,您将使用循环。我可以提供的一个很好的建议是,您希望将循环包装在事务中,因为如果没有AFAIK,则每个插入都将是一个自动事务,这将极大地影响时间。 (另外,在循环的结尾而不是在循环内提​​交。)

编辑:根据Python文档,

  

默认情况下,sqlite3模块在数据修改语言(DML)语句(即INSERT / UPDATE / DELETE / REPLACE之前隐式打开事务并提交在非DML,非查询语句(即SELECT或上述以外的任何内容)之前隐式进行事务。

因此,您在#method1中的代码正在执行[{BEGIN],INSERTCOMMIT,[BEGIN],INSERTCOMMIT ... BEGIN由Python隐式发送以开始事务,而COMMIT显式结束它。如果您按以下方式构建代码:

for item in data:
    cursor.execute("INSERT INTO table(value1, value2, value3) VALUES (?,?,?)", item)
conn.commit()

然后,您在开头有一个隐式BEGIN,在末尾有很多INSERTS和一个显式COMMIT。这样可以将您的代码速度提高10到20倍左右。