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