关于postgresql绑定变量的问题

发布于 2024-10-04 11:35:34 字数 633 浏览 14 评论 0原文

我正在查看 问题 并决定尝试使用绑定变量。我使用

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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

温馨耳语 2024-10-11 11:35:34

这些查询在 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 with cursor.executemany() and cursor.execute()

(But don't call it bind to pg people. Call it prepare or they may not know what you mean:)

浪菊怪哟 2024-10-11 11:35:34

重要更新
我已经查看了在 FreeBSD 端口中连接到 PostgreSQL 的所有 python 库的源代码,并且可以说,只有 py-postgresql 执行真正的准备好的语句!但它仅限于 Python 3+。

另外 py-pg_queue 是实现官方数据库协议(python 2.4+)的有趣库,


您错过了有关尽可能多地使用准备好的语句的问题的答案。 “绑定变量”是更好的形式,让我们看看:

sql_q = 'insert into abc (intfield, textfield) values (?, ?)'  # common form 
sql_b = 'insert into abc2 (intfield, textfield) values (:x , :y)' # should have driver and db support

所以你的测试应该是这样:

sql = 'insert into abc2 (intfield, textfield) values (:x , :y)'
for i in range (10000):
    cur.execute(sql, x=i, y='test')

或这样:

def _data(n):
    for i in range (n):
         yield (i, 'test')
sql = 'insert into abc2 (intfield, textfield) values (? , ?)'    
cur.executemany(sql, _data(10000))

等等。

更新:
我刚刚找到兴趣食谱 如何使用 %(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:

sql_q = 'insert into abc (intfield, textfield) values (?, ?)'  # common form 
sql_b = 'insert into abc2 (intfield, textfield) values (:x , :y)' # should have driver and db support

so your test should be this:

sql = 'insert into abc2 (intfield, textfield) values (:x , :y)'
for i in range (10000):
    cur.execute(sql, x=i, y='test')

or this:

def _data(n):
    for i in range (n):
         yield (i, 'test')
sql = 'insert into abc2 (intfield, textfield) values (? , ?)'    
cur.executemany(sql, _data(10000))

and so on.

UPDATE:
I've just found interest reciple how to transparently replace SQL queries with prepared and with usage of %(name)s

秋心╮凉 2024-10-11 11:35:34

据我所知,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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文