Eu tenho uma tabela (t0), no meu banco de dados Postgres, com dados mais ou menos assim:
t1_id t2_id
1 1
2 1
2 1
4 null
4 null
5 null
E eu tenho uma consulta para retornar meus resultados desejados de:
t1_id t2_id
1 1
4 null
5 null
Minha consulta é mais ou menos assim:
(
SELECT DISTINCT ON (t2_id) t1_id, t2_id
FROM t0
WHERE t2_id IS NOT NULL
)
UNION ALL
(
SELECT DISTINCT ON (t1_id) t1_id, t2_id
FROM t0
WHERE t2_id IS NULL
)
Existe uma maneira mais rápida de fazer uma operação como essa? Não é tão ruim, mas estou fazendo isso em vários lugares (com junções) e todas essas consultas repetidas parecem desacelerar um pouco as coisas. Parece que deve haver uma maneira melhor.
Aqui está a consulta em forma de violino: http://sqlfiddle.com/#!15/d41d8/3603
Para o caso simples, só consigo pensar em pequenas melhorias para a consulta:
Como o ypercube mencionou, você precisa adicionar
ORDER BY
uma lista inequívoca de expressões para obter resultados determinísticos.Você pode usar a constante
NULL
em vez det2_id
na segunda etapa da consulta. Também relevante para suporte abaixo do índice.A chave para o desempenho é a indexação . Tente dois índices parciais correspondentes às duas partes da consulta:
Você pode ou não querer incluir colunas adicionais para permitir varreduras somente de índice .
Dependendo do tamanho da tabela e distribuição de dados, pode haver alternativas mais rápidas :
solteiro
SELECT
Se você quiser condensá-lo em um único
SELECT
:Equivalente, exceto para ordem de classificação. Se você quiser que isso seja rápido, tente um índice funcional:
Dê seu exemplo, isso fará isso:
Basicamente, diz " faça um distinto em
t2_id
, mas se for,null
uset1_id
em vez disso ".