【问题标题】:Why is 'executemany' so slow compared to just doing an 'IN' query?为什么 'executemany' 比只做一个 'IN' 查询这么慢?
【发布时间】:2017-10-26 20:22:41
【问题描述】:

我的 MySQL 表架构是:

CREATE DATABASE test_db;
USE test_db;
CREATE TABLE test_table (
    id INT AUTO_INCREMENT,
    last_modified DATETIME NOT NULL,
    PRIMARY KEY (id)
) ENGINE=InnoDB;

当我运行以下基准脚本时,我得到:

b1:20.5559301376

b2:0.504406929016

from timeit import timeit
import MySQLdb

ids = range(1000)

query_1 = "update test_table set last_modified=UTC_TIMESTAMP() where id=%(id)s"
query_2 = "update test_table set last_modified=UTC_TIMESTAMP() where id in (%s)" % ", ".join(('%s', ) * len(ids))

db = MySQLdb.connect(host="localhost", user="some_user", passwd="some_pwd", db="test_db")

def b1():
    curs = db.cursor()
    curs.executemany(query_1, ids)
    db.close()

def b2():
    curs = db.cursor()
    curs.execute(query_2, ids)
    db.close()

print "b1: %s" % str(timeit(lambda:b1(), number=30))
print "b2: %s" % str(timeit(lambda:b2(), number=30))

为什么executemanyIN子句有这么大的区别?

我正在使用 Python 2.6.6 和 MySQL-python 1.2.3。

我能找到的唯一相关问题是 - Why is executemany slow in Python MySQLdb?,但这并不是我真正想要的。

【问题讨论】:

标签: python mysql performance mysql-python


【解决方案1】:

executemany 反复往返于 MySQL 服务器,然后需要解析查询、执行查询并返回结果。这可能比在单个 SQL 语句中执行所有操作的速度慢 10 倍,即使它更复杂。

但是,对于INSERTthis 表示它会做聪明的事情并为您构造一个多行INSERT,从而提高效率。

因此,IN(1,2,3,...)UPDATE;UPDATE;UPDATE... 效率更高

如果你有一个 id 序列,那么最好是 WHERE id BETWEEN 1 and 1000。这是因为它可以简单地扫描行而不是从头开始查找每一行。 (我假设id 被索引,可能是PRIMARY KEY。)

此外,您可能正在使用使每个插入/更新/删除进入其自己的“事务”的设置。这给每个UPDATE 增加了很多开销。在这种情况下,这可能是不可取的。我怀疑您希望整个 1000 行更新是原子的。

底线:仅将 executemany 用于 (a) INSERTs 或 (b) 必须单独运行的语句。

【讨论】:

猜你喜欢
  • 2011-03-11
  • 2020-03-19
  • 2014-03-12
  • 2011-02-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-05
  • 1970-01-01
相关资源
最近更新 更多