Disculpad la tardanza en contestar pero estamos en distinto uso horario,
detallo un poco mejor la situación, por simplicidad en la función que os he
mandado sólo hay un select pero en la función real hay unos diez, todos son
igual de simples que el que escribí, se selecciona un registro de una tabla con
un where por un campo (varchar) que a su vez tiene creado un indice, simple,
simple, y devuelvo en la función las 10 primary key que me devuelve cada
select. Esta función es llamada desde un programa en java, el caso es que se
ejecuta entre 400.000 y 800.000 veces y claro, aunque las diferencias tal y
cómo se han mostrado son pocas, al producirse en tantas ejecuciones sí que son
muy significativas. He probado varias cosas que habéis comentado:
- Poner dentro de la función la select sin parámetros poniendo el valor
directamente y me tarda más ó menos igual (0.230)
- ¿El auto_explain vale para ver los planes de todas las select que están
dentro de la función?, es que no he logrado ver la diferencia con hacer el
explain en cada select individualmente
- Lo que sí me ha funcionado es la sugerencia de Alvaro, desde la shell poner
el PREPARE y luego utilizar el EXPLAIN ANALIZE EXECUTE, con esto sí que los
tiempos son exactamente iguales que lanzar la consulta desde la shell (0.045)
Lo que no sé muy bien es cómo replicar este comportamiento dentro de la
función, ¿puedo hacer el PREPARE dentro de la función?, ¿tendría que hacerlo
por cada una de las 10 select que contiene la función y tras él el execute?,
¿tendría que descargar los prepare tras utilizar el execute ya que la función
se va a repetir 400.000 veces en la misma sesión?, la verdad es que no he
encontrado ejemplos de cómo hacer todo esto desde dentro de la función. Tampoco
sé si es la única opción ó si se os ocurre alguna otra forma menos laboriosa de
hacerlo.
Gracias a todos y saludos.
José Alberto Sánchez Nieto
Director Dpto. Tecnologías de la Información
Hiper Usera, S.L.
Pol. Industrial Las Avenidas · Torrejón de la Calzada C.P. 28991 (Madrid)
Tlf: 918609900 · Fax: 918160000
[email protected] <mailto:[email protected]>
No me imprimas si no es necesario. Protejamos el medio ambiente
Le informamos que su dirección de correo electrónico, asi como el resto de los
datos de carácter personal aportados, serán objeto de tratamiento automatizado
en nuestro ficheros, con la finalidad de gestionar la agenda de contactos de
nuestra empresa y, para poder atender a sus peticiones de consulta via
electronica. Vd.podrá en cualquier momento ejercer el derecho de acceso,
rectificación, cancelación y oposición en los términos establecidos en la Ley
Orgánica 15/1999 mediante notificación escrita con copia de DNI., a la entidad,
a través de éste e-mail.
La información incluida en este e-mail es CONFIDENCIAL, siendo para su usu
exlusivo del destinatario arriba mencionado. Si Usted lee este mensaje y no es
el destinatario indicado, le informamos de que está totalmente prohibida la
utilización, divulgación, distribución y/o reproducción de esta comunicaci´ón
sin autorización expresa en virtud de la legislacion vigente. Si ha recibido
este mensaje por error le rogamos nos o notifique inmediatamente por esta misma
vía y proceda a su eliminación.
> El 21 dic 2016, a las 19:59, Alvaro Herrera <[email protected]>
> escribió:
>
> "José Alberto Sánchez Nieto (Trabajo)" escribió:
>> Hola Ernesto, la versión que utilizo es la 9.6.1 y lo que utilizo es lo
>> siguiente:
>> - Desde shell:
>> select * from d_articulo where id_articulo = ‘2097’
>
> Esto no compara exactamente lo mismo, porque en plpgsql se usan planes
> preparados para las consultas SQL. Prueba esto:
>
> PREPARE articulos AS SELECT * FROM d_articulo WHERE id_articulo = $1;
> EXPLAIN ANALYZE EXECUTE articulos('2097');
>
> Debería ser lento como la función. Si lo es, muestra el EXPLAIN ANALYZE
> a ver qué dice.
>
> --
> Álvaro Herrera https://www.2ndQuadrant.com/
> PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services