关于postgresql绑定变量的问题
我正在查看 问题 并决定尝试使用绑定变量。我使用
sql = 'insert into abc2 (interfield,textfield) values (%s,%s)'
a = time.time()
for i in range(10000):
#just a wrapper around cursor.execute
db.executeUpdateCommand(sql,(i,'test'))
db.commit()
和
sql = 'insert into abc2 (intfield,textfield) values (%(x)s,%(y)s)'
for i in range(10000):
db.executeUpdateCommand(sql,{'x':i,'y':'test'})
db.commit()
查看两组所花费的时间,上面似乎没有太大的时间差异。事实上,第二个需要更长的时间。如果我在某个地方犯了错误,有人可以纠正我吗?在这里使用 psycopg2。
I was looking at the question and decided to try using the bind variables. I use
sql = 'insert into abc2 (interfield,textfield) values (%s,%s)'
a = time.time()
for i in range(10000):
#just a wrapper around cursor.execute
db.executeUpdateCommand(sql,(i,'test'))
db.commit()
and
sql = 'insert into abc2 (intfield,textfield) values (%(x)s,%(y)s)'
for i in range(10000):
db.executeUpdateCommand(sql,{'x':i,'y':'test'})
db.commit()
Looking at the time taken for the two sets, above it seems like there isn't much time difference. In fact, the second one takes longer. Can someone correct me if I've made a mistake somewhere? using psycopg2 here.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
这些查询在 Postgresql 中是等效的。
Bind 是 Oracle 行话。当您使用它时,它将保存查询计划,因此下次执行会快一点。
prepare
在 Postgres 中做同样的事情。http://www.postgresql.org/docs/current/static/sql -prepare.html
psycopg2 支持内部“绑定”,而不是使用
cursor.executemany()
和cursor.execute()
进行prepare
>(但不要称其为绑定到 pg 人员。称其为准备,否则他们可能不知道你的意思:)
The queries are equivalent in Postgresql.
Bind is oracle lingo. When you use it will save the query plan so the next execution will be a little faster.
prepare
does the same thing in Postgres.http://www.postgresql.org/docs/current/static/sql-prepare.html
psycopg2 supports an internal 'bind', not
prepare
withcursor.executemany()
andcursor.execute()
(But don't call it bind to pg people. Call it prepare or they may not know what you mean:)
重要更新:
我已经查看了在 FreeBSD 端口中连接到 PostgreSQL 的所有 python 库的源代码,并且可以说,只有 py-postgresql 执行真正的准备好的语句!但它仅限于 Python 3+。
另外 py-pg_queue 是实现官方数据库协议(python 2.4+)的有趣库,
您错过了有关尽可能多地使用准备好的语句的问题的答案。 “绑定变量”是更好的形式,让我们看看:
所以你的测试应该是这样:
或这样:
等等。
更新:
我刚刚找到兴趣食谱 如何使用 %(name)s 透明地替换 SQL 查询
IMPORTANT UPDATE :
I've seen into source of all python libraries to connect to PostgreSQL in FreeBSD ports and can say, that only py-postgresql does real prepared statements! But it is Python 3+ only.
also py-pg_queue is funny lib implementing official DB protocol (python 2.4+)
You've missed answer for that question about prepared statements to use as many as possible. "Binded variables" are better form of this, let's see:
so your test should be this:
or this:
and so on.
UPDATE:
I've just found interest reciple how to transparently replace SQL queries with prepared and with usage of %(name)s
据我所知,psycopg2 从未支持服务器端参数绑定(Oracle 术语中的“绑定变量”)。当前版本的 PostgreSQL 确实使用准备好的语句在协议级别支持它,但只有少数连接器库使用它。 Postgres wiki 在此处对此进行了注释。以下是您可能想要尝试的一些连接器:(我自己没有使用过这些连接器。)
只要您使用 DB-API 调用,您可能应该考虑使用cursor.executemany(),而不是重复调用cursor.execute()。
此外,在 PostgreSQL 中,将参数绑定到服务器(而不是连接器)中的查询并不总是更快。请注意此常见问题解答条目。
As far as I know, psycopg2 has never supported server-side parameter binding ("bind variables" in Oracle parlance). Current versions of PostgreSQL do support it at the protocol level using prepared statements, but only a few connector libraries make use of it. The Postgres wiki notes this here. Here are some connectors that you might want to try: (I haven't used these myself.)
As long as you're using DB-API calls, you probably ought to consider cursor.executemany() instead of repeatedly calling cursor.execute().
Also, binding parameters to their query in the server (instead of in the connector) is not always going to be faster in PostgreSQL. Note this FAQ entry.