Re: [pgsql-es-ayuda] Re: [pgsql-es-ayuda] Separación lógica de tablas, agrega rendimiento?

From: Jaime Casanova <jaime(dot)casanova(at)2ndquadrant(dot)com>
To: "Ivan Perales M(dot)" <ivan(dot)perales(at)gmail(dot)com>
Cc: Alvaro Herrera <alvherre(at)2ndquadrant(dot)com>, Ayuda Esp PostgreSQL <pgsql-es-ayuda(at)postgresql(dot)org>
Subject: Re: [pgsql-es-ayuda] Re: [pgsql-es-ayuda] Separación lógica de tablas, agrega rendimiento?
Date: 2016-04-21 02:12:38
Message-ID: CAJGNTeNwiEetx9d14mX44BUU9ds_=+WdJjqLQQwUYqjHKJP1yg@mail.gmail.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-es-ayuda

2016-04-19 17:25 GMT-05:00 Ivan Perales M. <ivan(dot)perales(at)gmail(dot)com>:
> Disculpen me equivoque, la consulta es así:
>
> select count(e.*) from cajas e
> left join material m on m.id = e.material_id
> where m.cliente_id = 10
>

Ya decia yo, porque en la consulta anterior no filtras nada realmente.

>>
>> Ya que el filtro no es directamente sobre la tabla cajas, tendrá que hacer
>> el join primero y luego ya con el index por defecto que tiene cliente_id
>> hacer el filtrado, pero para hacer el join hay que recorrer primero todo el
>> millón de registros no?

no.

el problema con tu consulta es que por alguna razón le pusieron LEFT JOIN
en lugar de INNER JOIN.

Claramente lo que quieres es lo segundo. porque el LEFT JOIN causa que
se seleccionen todos los registros de caja y si hubiera una caja sin registros
correspondientes en material igual aparece y los campos de material can con
NULL. Finalmente estas filtrando todos los registros que en el campo cliente
de material son diferentes a 10 (incluyendo los NULL)

Por ejemplo, supón las siguientes tablas con sus datos:

postgres=# select * from t1;
i
----
1
2
3
4
5
6
7
8
9
10
(10 filas)

postgres=# select * from t2;
i | f
---+-------------------------------
1 | 2017-06-25 00:45:11.118852-05
2 | 2016-11-07 12:32:11.118852-05
3 | 2017-03-25 23:29:11.118852-05
4 | 2016-04-06 17:20:11.118852-05
5 | 2016-04-11 20:31:11.118852-05
(5 filas)

como puedes ver *no* hay un registro correspondiente en t2 por cada
registro de t1
entonces ejecuta las siguientes sentencias y verás que

select * from t1 INNER JOIN t2 on t1.i = t2.i;

retorna 5 registros

select * from t1 LEFT JOIN t2 on t1.i = t2.i;

retorna 10 registros (los registros de t1 que no tienen
correspondencia en t2 salen
completados con NULL)

y si luego agregas

select * from t1 LEFT JOIN t2 on t1.i = t2.i where f IS NOT NULL;

nuevamente retorna solo 5 registros, eso es porque la clausula del WHERE
esta filtrando los registros que se habían completado con NULL causando
que la sentencia sea en esencia un INNER JOIN pero ineficiente porque
primero debe leer todos los registros de t1 completar con NULL y entonces
filtrar.

Que es lo mismo que tu estas haciendo en tu consulta con el "where
m.cliente = 10",
te aseguro que si cambias ese LEFT JOIN por INNER JOIN las cosas van a mejorar
mucho.

--
Jaime Casanova www.2ndQuadrant.com
PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services

-
Enviado a la lista de correo pgsql-es-ayuda (pgsql-es-ayuda(at)postgresql(dot)org)
Para cambiar tu suscripcin:
http://www.postgresql.org/mailpref/pgsql-es-ayuda

In response to

Browse pgsql-es-ayuda by date

  From Date Subject
Next Message Kernel 2016-04-21 12:29:43 Re: modos de bloqueo
Previous Message Jaime Casanova 2016-04-20 20:56:33 Re: modos de bloqueo