olá Matheus obrigado pela resposta, de fato esta query pode ser reescrita é
um exemplo bastante pobre mas o contexto se aplica em outras pesquisas que
tenho. Na verdade o tema da questão é a subquery no where, comecei a
analisar um software e este tipo de consulta é uma prática constante.

Via explain analyze percebi que utilizar constante ao invés de referência
aumenta o desempenho, o que já era de se esperar, porém nem em todos os
casos que tenho posso sugerir que alterem a referência cruzada por uma
constante.

Tentei utilizar o EXISTS mas também não deu liga, o fato é que sempre que
há uma referência ao escopo principal em uma subquery na cláusula WHERE
desta consulta, o sistema terá que resolver uma das leituras antes de
resolver a outra e terá que fazer um SEQ SCAN.

Fui infeliz no exemplo, segue outra pesquisa simples similar nesta mesma
estrutura:

SELECT
  CX.CODCAIXA , CX.DATATURNO
FROM
  CAIXA CX
WHERE
  CX.CODPROXCAIXA =
       (SELECT MAX (CX1.CODCAIXA )
          FROM CAIXA CX1
         WHERE CX1.CODHOTEL = CX.CODHOTEL )
  AND CX.CODHOTEL = 1

Valeu a dica

Em 19 de fevereiro de 2013 09:16, Matheus de Oliveira <
[email protected]> escreveu:

>
> 2013/2/19 Joel Benelli <[email protected]>
>
>> bom dia Fabrizio, o problema está na subquery do where, caso eu altere a
>> condição cruzada (CX1.CODHOTEL = CX.CODHOTEL) para uma constante
>> (CX1.CODHOTEL = 1) o tempo e o custo caem drasticamente. Obrigado pela
>> atenção.
>
>
> É claro que cai. Não são consultas equivalentes... =D
>
>
>> ----------------------------------------------------------------------------------
>> SELECT
>>   CX.CODCAIXA , CX.DATATURNO
>> FROM
>>   CAIXA CX
>> WHERE
>>   CX.CODCAIXA =
>>        (SELECT MAX (CX1.CODCAIXA )
>>           FROM CAIXA CX1
>>          WHERE CX1.CODHOTEL = CX.CODHOTEL )
>>   AND CX.CODHOTEL = 1
>>
>> ----------------------------------------------------------------------------------
>> "Seq Scan on caixa cx  (cost=0.00..960.76 rows=64 width=16)"
>> "  Filter: ((codhotel = 1) AND (codcaixa = (SubPlan 2)))"
>> "  SubPlan 2"
>> "    ->  Result  (cost=0.04..0.05 rows=1 width=0)"
>> "          InitPlan 1 (returns $1)"
>> "            ->  Limit  (cost=0.00..0.04 rows=1 width=4)"
>> "                  ->  Index Only Scan Backward using pk_caixa on caixa
>> cx1  (cost=0.00..466.81 rows=12878 width=4)"
>> "                        Index Cond: ((codhotel = cx.codhotel) AND
>> (codcaixa IS NOT NULL))"
>>
>> ----------------------------------------------------------------------------------
>> CREATE TABLE caixa
>> (
>>   dataturno timestamp(3) without time zone,
>>   turno integer,
>>   operador integer,
>>   salinidinheiro numeric(15,2),
>>   saliniom1 numeric(15,2),
>>   saliniom2 numeric(15,2),
>>   datahorainicio timestamp(3) without time zone,
>>   datahorafim timestamp(3) without time zone,
>>   cotacaoom1 numeric(15,2),
>>   cotacaoom2 numeric(15,2),
>>   codcaixa integer NOT NULL,
>>   codproxcaixa integer,
>>   codhotel integer NOT NULL,
>>   CONSTRAINT pk_caixa PRIMARY KEY (codhotel, codcaixa),
>>   CONSTRAINT idx_caixa_cdh_dtturno_turno UNIQUE (codhotel, dataturno,
>> turno)
>> )
>>
>>
> Por favor, use EXPLAIN ANALYZE, ajuda bastante.
>
> Uma consulta alternativa seria essa:
>
> SELECT
>   CX.CODCAIXA , CX.DATATURNO
> FROM
>   CAIXA CX
> WHERE
>   AND CX.CODHOTEL = 1
> ORDER BY CX.CODCAIXA DESC
> LIMIT 1
>
> Atenciosamente,
> --
> Matheus de Oliveira
> Analista de Banco de Dados
> Dextra Sistemas - MPS.Br nível F!
> www.dextra.com.br/postgres
>
>
> _______________________________________________
> pgbr-geral mailing list
> [email protected]
> https://listas.postgresql.org.br/cgi-bin/mailman/listinfo/pgbr-geral
>
>
_______________________________________________
pgbr-geral mailing list
[email protected]
https://listas.postgresql.org.br/cgi-bin/mailman/listinfo/pgbr-geral

Responder a