2010-11-24 6 views
5

Estaba mirando el question y decidí intentar usar las variables de vinculación. Yo usopregunta acerca de las variables de vinculación de 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() 

y

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() 

Mirando el tiempo necesario para que los dos conjuntos, por encima de ella parece que no hay mucha diferencia de tiempo. De hecho, el segundo lleva más tiempo. ¿Puede alguien corregirme si cometí un error en alguna parte? usando psycopg2 aquí.

Respuesta

7

Las consultas son equivalentes en Postgresql.

Enlazar es oracle lingo. Cuando lo use, guardará el plan de consulta para que la siguiente ejecución sea un poco más rápida. prepare hace lo mismo en Postgres.

http://www.postgresql.org/docs/current/static/sql-prepare.html

psycopg2 soporta una 'bind' interno, no prepare con cursor.executemany() y cursor.execute()

(Pero no lo llamamos unen a las personas pg. Llámese preparar o que puede no saber a qué se refiere :)

5

ACTUALIZACIÓN IMPORTANTE: que he visto en la fuente de todas las bibliotecas de python para conectar t o PostgreSQL en los puertos de FreeBSD y puede decir que solo py-postgresql hace declaraciones realmente preparadas! Pero es Python 3+ solamente.

también py-pg_queue es divertido lib implementación de protocolo oficial DB (Python 2.4+)


Te has perdido respuesta a esa pregunta sobre las declaraciones preparadas para utilizar el mayor número posible. "Variables de binded" están mejor forma de esto, vamos a ver:

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 

por lo que su ensayo deberá ser la siguiente:

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

o esto:

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

y así sucesivamente.

ACTUALIZACIÓN: Me acabo de encontrar interest reciple la forma de sustituir las consultas SQL de forma transparente con el preparado y con el uso de% (name) s

+0

@Eir, creo que en psycopg2 las variables de enlace se especifican como% (name) s, ¿no? – goh

+0

Seré muy cuidadoso con esta forma de SQL y posiblemente no la use en producción. –

+0

al menos en la forma% (name) s –

2

parámetro del lado del servidor Por lo que yo sé, nunca ha apoyado psycopg2 vinculante ("variables de vinculación" en el lenguaje de Oracle). Las versiones actuales de PostgreSQL sí lo soportan a nivel de protocolo usando declaraciones preparadas, pero solo unas pocas bibliotecas de conectores lo usan. El wiki de Postgres notes this here. Aquí hay algunos conectores que quizás desee probar: (Yo no los he usado yo.)

Mientras usted está utilizando llamadas DB-API, probablemente debería considerar cursor.executemany() en lugar de llamar repetidamente cursor. ejecutar().

Además, los parámetros de enlace a su consulta en el servidor (en lugar de en el conector) no siempre serán más rápidos en PostgreSQL. Nota this FAQ entry.

+0

cursor.executemany() es 'bind' para pyscopg2 http://initd.org/psycopg/docs/cursor.html#cursor.executemany –

+0

Usted lo pensaría, pero si mira el código fuente verá que psycopg2 usa el mismo código para execute() y execute many(). Hace su propio enlace de parámetros dentro de la biblioteca, en lugar de preparar una declaración y enviarla al servidor para su enlace. –

+0

Por lo tanto, executemany() de psycopg2 puede ser marginalmente más rápido que execute() permaneciendo en código compilado en lugar de volver al intérprete python muchas veces, pero todavía no está haciendo lo que implica cuando usas el término Oracle "bind variables". –

Cuestiones relacionadas