Psycopg2、Postgresql蟒蛇:最快的方式散装插入
-
20-09-2019 - |
题
我正在寻找最有效的方式批插入一些百万元组成一个数据库。我使用的Python,PostgreSQL和 psycopg2.
我已经创建了一个长长的清单tulpes,应插入的数据库,有时与改性剂像几何 Simplify
.
天真的方式来做到这将是串-格式列表 INSERT
发言,但有三种其他的方法我已经阅读一下:
- 使用
pyformat
结合的风格 对于参插入 - 使用
executemany
在清单元组, - 使用编写的结果文件和使用
COPY
.
看来,第一种方式是最有效的,但我赞赏你的见解和代码段告诉我如何做到这一权利。
解决方案
是的,我会投票的副本,供你可以写一个文件来的 服务器's硬盘驱动器(不驱动的应用程序的运行)作为复制只会读取关的服务器。
其他提示
有一个新的 psycopg2手册 含的例子所有的选项。
的 复制 选项是最有效的。然后executemany.然后将执行与pyformat.
以我的经验 executemany
不是任何运行速度快于许多插入自己,
最快的方法是一个单一的格式 INSERT
有许多值自己,也许在未来 executemany
将会改善,但是现在它是相当缓慢
我一个子类 list
和超负荷的追加方法,因此当一名单达到一定的大小格式插入运行它
你可以用 一个新的更新插入图书馆:
$ pip install upsert
(你可能要 pip install decorator
第一个)
conn = psycopg2.connect('dbname=mydatabase')
cur = conn.cursor()
upsert = Upsert(cur, 'mytable')
for (selector, setter) in myrecords:
upsert.row(selector, setter)
哪里 selector
是一个 dict
对象喜欢 {'name': 'Chris Smith'}
和 setter
是一个 dict
喜欢 { 'age': 28, 'state': 'WI' }
它的 几乎 尽快编写定义插入[/更新]码和运行直接与 psycopg2
...它不会爆炸,如果该行已经存在。
任何人使用SQLalchemy可以尝试1.2版,其中加入支持的大容量插入使用psycopg2.演员。execute_batch()而不是executemany当你初始化你的引擎与use_batch_mode=True如:
engine = create_engine(
"postgresql+psycopg2://scott:tiger@host/dbname",
use_batch_mode=True)
http://docs.sqlalchemy.org/en/latest/changelog/migration_12.html#change-4109
然后有人将必须使用SQLalchmey不会打扰到尝试不同的组合sqla和psycopg2和直接SQL在一起。
第一和第二的将是一起使用,不分开。第三,将是最有效的服务器的明智虽然,由于服务器会做 所有 艰苦的工作。
在一些测试 取消嵌套 往往似乎是一个非常快速的选择,因为我学到从 @Clodoaldo Neto's 答案 一个类似的问题。
data = [(1, 100), (2, 200), ...] # list of tuples
cur.execute("""CREATE TABLE table1 AS
SELECT u.id, u.var1
FROM unnest(%s) u(id INT, var1 INT)""", (data,))
然而,它的 可能是棘手有非常大的数据.
一个非常相关的问题: 批量插入与SQLAlchemy奥姆
条条大路通罗马, 但他们中的一些越过山脉,要求渡轮,但是如果你想获得有迅速采取高速公路。
在这种情况下的高速公路的使用 execute_batch() 特征 psycopg2.该文件说,它最好的:
目前的执行情况 executemany()
是(利用一个非常慈善保守的说法)不是特别的执行。这些功能可以用于加速的反复执行的一项声明根据一组参数。通过减少往返服务器的性能可以订购的幅度比使用 executemany()
.
在我自己的测试 execute_batch()
是 大约快两倍 作为 executemany()
, ,并提供了选项配置page_size进一步调整(如果你想挤过去的2-3%,表现出driver)。
同样的功能可以很容易地启用,如果您使用的是SQLAlchemy通过设置 use_batch_mode=True
作为一个参数的时候你的实例引擎 create_engine()