Mejorar rendimiento de PostgreSQL

2,376 views
Skip to first unread message

DeZeta

unread,
Apr 25, 2013, 2:28:18 PM4/25/13
to ene...@googlegroups.com
Buenas

Estamos implantando el coste medio de stock en un cliente a posteriori, lo que quiere decir que hay que recalcular, de forma retroactiva, los costes en los albaranes y facturas ya hechos. En fin, un folllón.

El caso es que hay que lanzar montones de veces (miles) consultas como por ejemplo esta:

SELECT SUM(lineasfacturascli.cantidad) 
FROM lineasfacturascli inner join facturascli on facturascli.idfactura = lineasfacturascli.idfactura
WHERE lineasfacturascli.referencia = '027006' and facturascli.codalmacen = 'ALG' and 
facturascli.fecha+facturascli.hora > '2013-04-09T12:59:58' and 
facturascli.fecha+facturascli.hora <= '2013-04-12T00:00:00' 
GROUP BY lineasfacturascli.referencia

Nos vendría de perlas alguna idea sobre cómo mejorar el rendimiento de PostgreSQL con estas consultas, ya que actualmente el cálculo para un año necesita varios días.

He puesto índices en las tablas:
CREATE INDEX facturascli_cms_calc_facturas
  ON facturascli
  USING btree
  (codalmacen, fecha, hora);

CREATE INDEX lineasfacturascli_cms
  ON lineasfacturascli
  USING btree
  (idfactura, referencia);

Pero no aprecio mucha mejora.

No sé si se pueden crear índices "cruzados", es decir, que optimicen consultas sobre varias tablas con JOIN.

¿Alguna idea?

Saludos,

David Zafra
KLO

deavid

unread,
Apr 25, 2013, 2:53:41 PM4/25/13
to ene...@googlegroups.com
Hola David! A ver si puedo ayudar un poco.

Por una parte, no, no se pueden crear índices cruzados. Sería muy
chulo, pero internamente creo que es casi imposible de implementar y
que sea rápido. Así que no hay, una pena. A veces, si una columna es
muy interesante para filtrar una tabla hija, te va a tocar copiarla.
Además, conociendo otras bases de datos más esotéricas (MongoDB,
Cassandra, etc), te puedo decir que es una aproximación muy válida.

Por otra parte, ten en cuenta que nosotros estamos metiendo mucha caña
a PostgreSQL y conseguimos la mayoría de las cosas en el orden de las
décimas de segundo.

Una cosa que sí he notado es un error en el índice que pretendes
crear. Has puesto (codalmacen, fecha, hora), cuando deberías haber
puesto (codalmacen, fecha+hora) ya que el campo que estás comparando
está calculado. Debes indexar el cálculo.
Pero yo iría aún más allá: No indexaría la hora ni preguntaría por
ella. Me parece un poco absurdo, estás perdiendo algo de eficiencia,
el índice puede ser más pequeño y con menos "cardinalidad".

Pregunta por (fecha BETWEEN fechaA AND fechaB) y fin del problema.

Copiar la fecha dentro de las líneas aceleraría la consulta mucho.
Pero eso te va a traer otros dolores de cabeza (cómo mantener ese
campo).

Y aquí viene la parte importante: En qué varían esos miles de
consultas? La referencia? El rango de fecha? ambas?
El problema principal es que estás haciendo que postgresql examine una
y otra vez lo mismo, para obtener cosas distintas, cuando a menudo se
puede hacer de golpe o casi de golpe. O particionando, pero con una
estrategia que optimice las lecturas de los datos.

Un último consejo: Personaliza postgresql.conf para que planifique
correctamente, revisa con PgAdmin3 la planificación. Asegurate que el
servidor tiene al menos 1Gb de ram libre (sin usar o en caché).
> --
> Has recibido este mensaje porque estás suscrito al grupo "Eneboo" de Grupos
> de Google.
> Para anular la suscripción a este grupo y dejar de recibir sus correos
> electrónicos, envía un correo electrónico a
> eneboo+un...@googlegroups.com.
> Para obtener más opciones, visita https://groups.google.com/groups/opt_out.
>
>

deavid

unread,
Apr 25, 2013, 3:07:13 PM4/25/13
to ene...@googlegroups.com
Bueno, me dejaba tal vez una de las optimizaciones más importantes,
pero como es un poco complicada, la pongo aquí en un correo a parte.
Hay una estrategia de consulta que PostgreSQL no termina de hacer bien
o no lo ve, supongo que es porque el planificador no tiene suficientes
datos sin lanzar realmente la query.
Comentabas si se puede hacer un índice que cruce tablas... no se
puede, pero se puede extrapolar a una query en dos pasos. Y es *muy*
eficiente.

La idea: evitar copiar la columna de fecha y usar idfactura en su
lugar. Es decir, le vamos a dar de antemano que valores de idfactura
tiene que mirar.

La idea es obtener el conjunto de valores idfactura para el rango de
fechas especificado, y luego escribirlo dentro de un IN () ... o en
caso de una función de PL/PGSQL, lo guardamos en un integer[] y lo
comparamos con "idfactura = ANY(array_idfactura)".

Luego con la segunda query, no necesitaríamos la tabla facturascli para nada.

Mucho ojo: si vamos a preguntar para cada referencia en el rango de
fechas, hay que obtener los idfactura una única vez.

Esto es eficiente porque PostgreSQL usará un "Bitmap Scan"
(exceptuando versiones antiguas), esto hace que lea el índice de forma
rápida y eficiente, saltando lo que no le interesa. En las demás
aproximaciones tiende a leer la tabla entera o usar algún sistema
complejo para cruzar los datos.

José Antonio Fernández Fernández

unread,
Apr 25, 2013, 3:09:40 PM4/25/13
to ene...@googlegroups.com
Cada vez que abre la boca el tio este nos deja más insignificantes . jajaja XD +1
--
Cuenta de correo propiedad de FERNÁNDEZ FERNÁNDEZ, JOSÉ ANTONIO y de uso estrictamente profesional. Este mensaje electrónico está dirigido únicamente a la(s) direcciones indicadas anteriormente: el carácter confidencial, personal e intransferible del mismo está protegido legalmente.
Cualquier revelación, uso o reenvío no autorizado, completo o en parte está prohibido. Si ha recibido este mensaje por equivocación notifíquelo inmediatamente a la persona que lo remite y borre el mensaje original junto con sus ficheros anexos sin leerlo ni grabarlo total o parcialmente. Si usted no desea recibir correos de nuestra empresa, por favor, envíenos un correo a AULLAS...@GMAIL.COM manifestando tal deseo

deavid

unread,
Apr 25, 2013, 3:55:36 PM4/25/13
to ene...@googlegroups.com
GROUP BY codalmacen, referencia
Venga, último apunte y me callo ya :-D

Supongamos que tienes 50k facturas con 50 líneas cada una, unas 2500k
filas en lineasfacturas. (La más grande que he visto tenía 1200k) Y lo
que queremos es obtener sumatorios varios para *todas* las líneas de
factura, agrupando por distintos rangos de fechas y por referencia.
Creo que esto es lo que intentas hacer más o menos.

¿Cómo haría yo eso? muy sencillo...

1.- Obtener la relación de agrupado de rango_fecha[] -> idfactura[]
Es decir, para cada rango de fecha a analizar (pongamos que es cada 4
días), el listado de los "idfactura" que existen.
Para ello, un FLSqlQuery: SELECT idfactura, fecha FROM facturascli
ORDER BY fecha, idfactura
Conforme voy leyendo, voy montando los arrays. Ojo, dependiendo del
algoritmo para montar los arrays, es posible que el ORDER BY
fecha,idfactura sea innecesario. Si existe una función que rápidamente
para una fecha nos da una clave única de rango, el ORDER BY lo único
que haría es hacer las cosas más lentas.

Con esto, deberíamos tener un array tipo:
rango[0] = [1,5,6,8,9...]
rango[1] = [12,13,14,..]
rango[n] = [....]

Por muchas facturas que tengamos dudo que haya problemas de memoria por esto.

Con esto pasaría a consultar todo lineasfacturascli, pero consultar
todo de golpe además de ser dificil, probablemente se generen muchos
registros, una transacción bastante pesada. Particionar puede ser una
buena solución aquí. Ahora podemos particionar por rango, por
referencia o por codalmacen. ¿Cual es la mejor?

La mejor es por rango. Porque es la forma en que están organizadas las
filas en disco. Seleccionar uno o más rangos contíguos casi con total
seguridad nos dará que tenemos las líneas contiguas. Así que leemos
menos disco y más de golpe. Sería algo así: (pseudocódigo QS/SQL)

for(n in rango) {
lista = rango[n];

SELECT codalmacen, referencia, SUM(cantidad), SUM(pvptotal) FROM
lineasfacturascli
WHERE idfactura IN $(LISTA)
GROUP BY codalmacen, referencia
ORDER BY codalmacen, referencia

}

Para que funcione vas a necesitar un índice en
lineasfacturascli.idfactura (supongo que ya lo tienes).
Indexar codalmacen y/o referencia creo que no tiene apenas impacto.

Apostaría algo a que no tarda ni 10 minutos en completar si se implementa bien.

El día 25 de abril de 2013 21:09, José Antonio Fernández Fernández
<aullas...@gmail.com> escribió:

DeZeta

unread,
Apr 25, 2013, 4:04:25 PM4/25/13
to ene...@googlegroups.com
Muchas gracias tocayo, grande como siempre. Guardo tus consejos como oro en paño para sacarles brillo. Iré comentando los resultados por aquí. ¡Cuánto vamos a aprender!

Un abrazo.

DeZeta

unread,
Apr 25, 2013, 8:12:21 PM4/25/13
to ene...@googlegroups.com

Una cosa que sí he notado es un error en el índice que pretendes
crear. Has puesto (codalmacen, fecha, hora), cuando deberías haber
puesto (codalmacen, fecha+hora) ya que el campo que estás comparando
está calculado. Debes indexar el cálculo.

Primer gran avance. En recalcular todos los costes de albaranes de un día concreto, antes del cambio tardaba 6 minutos, y después sólo 1:36. ¡Espectacular!

Importante: hay que poner el cálculo entre paréntesis, si no da error.
(codalmacen, (fecha+hora))

Seguiremos probando cosas. Después de muchas noches acostándome cabreado, hoy me voy a la cama contento :-) 

José Antonio Cuello

unread,
Apr 26, 2013, 2:39:10 AM4/26/13
to ene...@googlegroups.com
Hola, has probado poner los filtros de facturascli dentro del join, eso hará que al ser inner join se procesen muchas menos lineas en la selección. Por otra parte si el indice lo creas ((fecha+hora), codalmacen) será más optimo puesto que el campo que más varia es el de fecha por lo que el indice estará más optimizado para tus búsquedas descartando los registros que no cumplan el where con mayor celeridad.

Un saludo


--

José Antonio Cuello

unread,
Apr 26, 2013, 2:41:58 AM4/26/13
to ene...@googlegroups.com
Otra cosa respecto al BETWEEN en comparación con tu ejemplo de SELECT. El BETWEEN incluye los dos rangos, es decir >= y <=, mientras que en tu ejemplo pone > y luego <=

Un cordial saludo.

David Zafra Gómez

unread,
Apr 26, 2013, 7:45:51 AM4/26/13
to ene...@googlegroups.com
Mmmm, retoques sencillos y que tienen buena pinta. Me gusta.

Gracias Jos� Antonio, probar� a ver qu� tal.

Saludos,

David

El 26/04/13 08:39, Jos� Antonio Cuello escribi�:
> Hola, has probado poner los filtros de facturascli dentro del join,
> eso har� que al ser inner join se procesen muchas menos lineas en la
> selecci�n. Por otra parte si el indice lo creas ((fecha+hora),
> codalmacen) ser� m�s optimo puesto que el campo que m�s varia es el de
> fecha por lo que el indice estar� m�s optimizado para tus b�squedas

David Zafra Gómez

unread,
Apr 26, 2013, 7:50:22 AM4/26/13
to ene...@googlegroups.com
El 25/04/13 20:53, deavid escribi�:
> No indexar�a la hora ni preguntar�a por
> ella. Me parece un poco absurdo, est�s perdiendo algo de eficiencia,
> el �ndice puede ser m�s peque�o y con menos "cardinalidad".
Necesito la hora para que funcionen bien los c�lculos porque, dentro de
un mismo d�a, no es lo mismo si un albar�n de compra entra antes o
despu�s que uno de venta.

Podr�a quitarlo del �ndice y controlar lo de ha hora dentro del bucle
que recorre el cursor, saltando los registros que est�n fuera del intervalo.

Saludos.

David Zafra Gómez

unread,
Apr 26, 2013, 7:53:40 AM4/26/13
to ene...@googlegroups.com
El 26/04/13 08:41, Jos� Antonio Cuello escribi�:
> Otra cosa respecto al BETWEEN en comparaci�n con tu ejemplo de SELECT.
> El BETWEEN incluye los dos rangos, es decir >= y <=, mientras que en
> tu ejemplo pone > y luego <=
Gracias por el aviso, es importante tenerlo en cuenta.

Saludazos.

deavid

unread,
Apr 26, 2013, 7:57:55 AM4/26/13
to ene...@googlegroups.com
Lo quitas del índice, pero luego lo vuelves a comparar. Eso no es problema.
Es decir, puedes hacer lo siguiente:

CREATE INDEX facturascli_fecha
ON facturascli
USING btree
(fecha);


SELECT SUM(lineasfacturascli.cantidad)
FROM lineasfacturascli inner join facturascli on facturascli.idfactura
= lineasfacturascli.idfactura
WHERE
(facturascli.fecha BETWEEN '2013-04-09' and '2013-04-12') and
lineasfacturascli.referencia = '027006' and facturascli.codalmacen = 'ALG' and
facturascli.fecha+facturascli.hora > '2013-04-09T12:59:58' and
facturascli.fecha+facturascli.hora <= '2013-04-12T00:00:00'
GROUP BY lineasfacturascli.referencia

Con el primer filtro, invocas el índice, filtrando los resultados lo
máximo posible (aunque con falsos positivos). Luego ya "refiltras" por
lo que necesites, aunque sea por el mismo campo.


El día 26 de abril de 2013 13:50, David Zafra Gómez <dez...@klo.es> escribió:
> El 25/04/13 20:53, deavid escribió:
>
>> No indexaría la hora ni preguntaría por
>> ella. Me parece un poco absurdo, estás perdiendo algo de eficiencia,
>> el índice puede ser más pequeño y con menos "cardinalidad".
>
> Necesito la hora para que funcionen bien los cálculos porque, dentro de un
> mismo día, no es lo mismo si un albarán de compra entra antes o después que
> uno de venta.
>
> Podría quitarlo del índice y controlar lo de ha hora dentro del bucle que
> recorre el cursor, saltando los registros que estén fuera del intervalo.
>
> Saludos.

David Zafra Gómez

unread,
Apr 26, 2013, 8:02:17 AM4/26/13
to ene...@googlegroups.com
Arrea, no sab�a eso del "refiltrado". Muuuy interesante. Ponme a los
pies de tu se�ora ;-).

El 26/04/13 13:57, deavid escribi�:
> Lo quitas del �ndice, pero luego lo vuelves a comparar. Eso no es problema.
> Es decir, puedes hacer lo siguiente:
>
> CREATE INDEX facturascli_fecha
> ON facturascli
> USING btree
> (fecha);
>
>
> SELECT SUM(lineasfacturascli.cantidad)
> FROM lineasfacturascli inner join facturascli on facturascli.idfactura
> = lineasfacturascli.idfactura
> WHERE
> (facturascli.fecha BETWEEN '2013-04-09' and '2013-04-12') and
> lineasfacturascli.referencia = '027006' and facturascli.codalmacen = 'ALG' and
> facturascli.fecha+facturascli.hora > '2013-04-09T12:59:58' and
> facturascli.fecha+facturascli.hora <= '2013-04-12T00:00:00'
> GROUP BY lineasfacturascli.referencia
>
> Con el primer filtro, invocas el �ndice, filtrando los resultados lo
> m�ximo posible (aunque con falsos positivos). Luego ya "refiltras" por

Manuel Calomarde Gomez

unread,
Apr 26, 2013, 10:51:28 AM4/26/13
to ene...@googlegroups.com
...oño David, lo tuyo es ost.....  ¿Dónde hay que echar las solicitudes para el premio Principe de Asturias de este año?

Saludos :-)

DeZeta

unread,
Apr 26, 2013, 2:27:40 PM4/26/13
to ene...@googlegroups.com

Por otra parte si el indice lo creas ((fecha+hora), codalmacen) será más optimo puesto que el campo que más varia es el de fecha por lo que el indice estará más optimizado para tus búsquedas descartando los registros que no cumplan el where con mayor celeridad.

He modificado todos los índices que he creado para el cálculo siguiendo la premisa de poner primero los campos que más cambian. El rendimiento ha mejorado casi un 10%. Si lo he entendido bien, esto es así porque de esta forma se descartan antes registros que no cumplen las primeras condiciones y no hace falta comprobar el resto de los campos del índice. ¿Es así?

Gracias Jose.

José Antonio Cuello

unread,
Apr 26, 2013, 4:04:16 PM4/26/13
to ene...@googlegroups.com
Si, es el mismo caso que el inner join ... si pones la condición de fecha en el inner join en vez del where los registros se descartan al crear el subconjunto cartesiano de tabla maestra + tabla hija sin necesitar de llegar al where y por descontado a un posible order by

Me alegro que te haya servido. Tambien puedes recurrir al PSQL y programar dentro del servidor PostgreSQL mediante cursores puedes hacer búsquedas masivas del tipo 

hago select de las cabeceras de pedido
  por cada cabecera busco su detalle

Bien programado, si el servidor cuanta con bastante memoria te aseguro que los procedimientos vuelan. Tengo estadisticas que comparan distintos años, incluso una que calcula los 20 productos mas vendidos por importe y por cantidad y luego compara las ventas de los clientes indicando que productos de los más vendidos no ha comprado. No tarda a penas un minuto o menos en calcularlo. Pero no te lo he sugerido antes porque no se si te interesa casarte con una base de datos o mantener compatibilidad.

Si te puede servir te mando los procedimientos. Un saludo.

David Zafra Gómez

unread,
Apr 27, 2013, 7:12:05 AM4/27/13
to ene...@googlegroups.com
Me interesa, Jos� Antonio. No tenemos intenci�n de cambiar de base de datos.

Gracias de nuevo.

Saludos,

David

El 26/04/13 22:04, Jos� Antonio Cuello escribi�:
> Si, es el mismo caso que el inner join ... si pones la condici�n de
> fecha en el inner join en vez del where los registros se descartan al
> crear el subconjunto cartesiano de tabla maestra + tabla hija sin
> necesitar de llegar al where y por descontado a un posible order by
>
> Me alegro que te haya servido. Tambien puedes recurrir al PSQL y
> programar dentro del servidor PostgreSQL mediante cursores puedes
> hacer b�squedas masivas del tipo
>
> hago select de las cabeceras de pedido
> por cada cabecera busco su detalle
>
> Bien programado, si el servidor cuanta con bastante memoria te aseguro
> que los procedimientos vuelan. Tengo estadisticas que comparan
> distintos a�os, incluso una que calcula los 20 productos mas vendidos
> por importe y por cantidad y luego compara las ventas de los clientes
> indicando que productos de los m�s vendidos no ha comprado. No tarda a
> penas un minuto o menos en calcularlo. Pero no te lo he sugerido antes
> porque no se si te interesa casarte con una base de datos o mantener
> compatibilidad.
>
> Si te puede servir te mando los procedimientos. Un saludo.
>
> --
> Has recibido este mensaje porque est�s suscrito al grupo "Eneboo" de
> Grupos de Google.
> Para anular la suscripci�n a este grupo y dejar de recibir sus correos
> electr�nicos, env�a un correo electr�nico a
> eneboo+un...@googlegroups.com.
> Para obtener m�s opciones, visita
> https://groups.google.com/groups/opt_out.
>
>

José Antonio Cuello

unread,
Apr 27, 2013, 4:53:51 PM4/27/13
to ene...@googlegroups.com
Te adjunto una serie de archivos con funciones donde uso cursores. Como estas funciones usan vistas te paso las declaraciones de las vistas.

también te recomiendo la lectura de las windows function disponibles desde postgresql 8.4 (son funciones estadisticas avanzadas)

http://www.postgresql.org.es/node/376                                     (doc no oficial en castellano)

Espero puedan aportate ideas de cómo desarrollar la necesidad del cliente. Por otro lado, si os puedo ser de ayuda basta me concretéis un poco más el proceso que necesitáis y puedo mirar de pensar algo más concreto.

Un saludo.


El 27 de abril de 2013 13:12, David Zafra Gómez <dez...@klo.es> escribió:
Me interesa, José Antonio. No tenemos intención de cambiar de base de datos.


Gracias de nuevo.

Saludos,

David

El 26/04/13 22:04, José Antonio Cuello escribió:
Si, es el mismo caso que el inner join ... si pones la condición de fecha en el inner join en vez del where los registros se descartan al crear el subconjunto cartesiano de tabla maestra + tabla hija sin necesitar de llegar al where y por descontado a un posible order by

Me alegro que te haya servido. Tambien puedes recurrir al PSQL y programar dentro del servidor PostgreSQL mediante cursores puedes hacer búsquedas masivas del tipo


hago select de las cabeceras de pedido
  por cada cabecera busco su detalle

Bien programado, si el servidor cuanta con bastante memoria te aseguro que los procedimientos vuelan. Tengo estadisticas que comparan distintos años, incluso una que calcula los 20 productos mas vendidos por importe y por cantidad y luego compara las ventas de los clientes indicando que productos de los más vendidos no ha comprado. No tarda a penas un minuto o menos en calcularlo. Pero no te lo he sugerido antes porque no se si te interesa casarte con una base de datos o mantener compatibilidad.


Si te puede servir te mando los procedimientos. Un saludo.

--
Has recibido este mensaje porque estás suscrito al grupo "Eneboo" de Grupos de Google.
Para anular la suscripción a este grupo y dejar de recibir sus correos electrónicos, envía un correo electrónico a eneboo+unsubscribe@googlegroups.com.

Para obtener más opciones, visita https://groups.google.com/groups/opt_out.



--
Has recibido este mensaje porque estás suscrito al grupo "Eneboo" de Grupos de Google.
Para anular la suscripción a este grupo y dejar de recibir sus correos electrónicos, envía un correo electrónico a eneboo+unsubscribe@googlegroups.com.
axfunc_masvendidosclientes.sql
axfunc_ventasclientes.sql
sql functions.sql
artex_comprasventas.sql

David Zafra Gómez

unread,
Apr 30, 2013, 8:44:51 AM4/30/13
to ene...@googlegroups.com
Cómo te lo has currado. +100

El 27/04/13 22:53, José Antonio Cuello escribió:
Te adjunto una serie de archivos con funciones donde uso cursores. Como estas funciones usan vistas te paso las declaraciones de las vistas.

también te recomiendo la lectura de las windows function disponibles desde postgresql 8.4 (son funciones estadisticas avanzadas)

http://www.postgresql.org.es/node/376                                     (doc no oficial en castellano)

Espero puedan aportate ideas de cómo desarrollar la necesidad del cliente. Por otro lado, si os puedo ser de ayuda basta me concretéis un poco más el proceso que necesitáis y puedo mirar de pensar algo más concreto.

Un saludo.
El 27 de abril de 2013 13:12, David Zafra Gómez <dez...@klo.es> escribió:
Me interesa, José Antonio. No tenemos intención de cambiar de base de datos.

Gracias de nuevo.

Saludos,

David

El 26/04/13 22:04, José Antonio Cuello escribió:
Si, es el mismo caso que el inner join ... si pones la condición de fecha en el inner join en vez del where los registros se descartan al crear el subconjunto cartesiano de tabla maestra + tabla hija sin necesitar de llegar al where y por descontado a un posible order by

Me alegro que te haya servido. Tambien puedes recurrir al PSQL y programar dentro del servidor PostgreSQL mediante cursores puedes hacer búsquedas masivas del tipo

hago select de las cabeceras de pedido
  por cada cabecera busco su detalle

Bien programado, si el servidor cuanta con bastante memoria te aseguro que los procedimientos vuelan. Tengo estadisticas que comparan distintos años, incluso una que calcula los 20 productos mas vendidos por importe y por cantidad y luego compara las ventas de los clientes indicando que productos de los más vendidos no ha comprado. No tarda a penas un minuto o menos en calcularlo. Pero no te lo he sugerido antes porque no se si te interesa casarte con una base de datos o mantener compatibilidad.

Si te puede servir te mando los procedimientos. Un saludo.

--
Has recibido este mensaje porque estás suscrito al grupo "Eneboo" de Grupos de Google.
Para anular la suscripción a este grupo y dejar de recibir sus correos electrónicos, envía un correo electrónico a eneboo+un...@googlegroups.com.

Para obtener más opciones, visita https://groups.google.com/groups/opt_out.



--
Has recibido este mensaje porque estás suscrito al grupo "Eneboo" de Grupos de Google.
Para anular la suscripción a este grupo y dejar de recibir sus correos electrónicos, envía un correo electrónico a eneboo+un...@googlegroups.com.

Para obtener más opciones, visita https://groups.google.com/groups/opt_out.


--
Has recibido este mensaje porque estás suscrito al grupo "Eneboo" de Grupos de Google.
Para anular la suscripción a este grupo y dejar de recibir sus correos electrónicos, envía un correo electrónico a eneboo+un...@googlegroups.com.

DeZeta

unread,
May 16, 2013, 6:34:57 PM5/16/13
to ene...@googlegroups.com

Pregunta por (fecha BETWEEN fechaA AND fechaB) y fin del problema. 

Esto ha funcionado muy bien. Una mejora del rendimiento en torno al 20%. :-)

DeZeta

unread,
May 16, 2013, 6:38:45 PM5/16/13
to ene...@googlegroups.com
Lo quitas del índice, pero luego lo vuelves a comparar. Eso no es problema.
Es decir, puedes hacer lo siguiente:

CREATE INDEX facturascli_fecha
  ON facturascli
  USING btree
  (fecha);


SELECT SUM(lineasfacturascli.cantidad)
FROM lineasfacturascli inner join facturascli on facturascli.idfactura
= lineasfacturascli.idfactura
WHERE
(facturascli.fecha BETWEEN '2013-04-09' and '2013-04-12') and
lineasfacturascli.referencia = '027006' and facturascli.codalmacen = 'ALG' and
facturascli.fecha+facturascli.hora > '2013-04-09T12:59:58' and
facturascli.fecha+facturascli.hora <= '2013-04-12T00:00:00'
GROUP BY lineasfacturascli.referencia

Esto no ha dado buenos resultados, todo lo contrario, el rendimiento ha empeorado bastante. La comparación facturascli.fecha+facturascli.hora ralentiza muchíiisimo la consulta. He probado a meter en el índice tanto "fecha" como "fecha+hora", pero la cosa no ha mejorado.

Saludos,

David

José Antonio Cuello

unread,
May 17, 2013, 4:09:28 AM5/17/13
to ene...@googlegroups.com
Has intentado filtrar en el INNER JOIN facturascli por la fecha.

De esta manera al realizar el WHERE fecha+hora serán muchos menos registros a comparar.

Un saludo


--

deavid

unread,
May 17, 2013, 4:20:11 AM5/17/13
to ene...@googlegroups.com
Aparte de eso, yo miraría la configuración del planificador... o mirar
qué está haciendo con un explain.

El día 17 de mayo de 2013 10:09, José Antonio Cuello
<yopl...@gmail.com> escribió:

David Zafra Gómez

unread,
May 17, 2013, 4:27:50 AM5/17/13
to ene...@googlegroups.com
Probaré vuestros sabios consejos. ¡Gracias a los dos!

El 17/05/13 00:38, DeZeta escribió:
Reply all
Reply to author
Forward
0 new messages