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