Hola Jose te comento entre lineas:

On 22/12/16 07:39, "José Alberto Sánchez Nieto (Trabajo)" wrote:
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
En la documetacion (https://www.postgresql.org/docs/9.6/static/auto-explain.html) hablan de varios parametros, creo que debes ajustar:
auto_explain.log_min_duration
auto_explain.log_nested_statements

Asegúrate de tener las estadísticas actualizadas en los momentos de las pruebas para que el optimizador tome el mejor plan


Saludos

- 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.
Firmas de <a href="http://correo.com"; class="">correo.com</a> : José Alberto Sánchez Nieto
        
Logo    

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*
albertosanc...@hiperusera.es <mailto:albertosanc...@hiperusera.es>

eco 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 <alvhe...@2ndquadrant.com <mailto:alvhe...@2ndquadrant.com>> 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/ <https://www.2ndquadrant.com/>
PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services


Responder a