A consulta a seguir obtém o último relatório (onde latitude, longitude e segundos são <> 0
) associado às unidades especificadas:
SELECT
reports.*
FROM
reports
INNER JOIN
units
ON units.id = reports.unit_id
WHERE
reports.unit_id IN (1111, 1112, 1113)
AND
(
reports.id =
(
SELECT reports.id
FROM reports
WHERE reports.unit_id = units.id
AND
reports.time_secs != 0
AND
reports.latitude != 0.0
AND
reports.longitude != 0.0
ORDER BY time desc
LIMIT 1
)
)
Essa consulta levou vários minutos para ser executada e gostaria de saber se há uma otimização que eu possa fazer nela.
Isso pode ser consideravelmente mais simples e rápido com
DISTINCT ON
:Mais explicações nestas respostas relacionadas:
Como obtenho com eficiência "a linha correspondente mais recente"?
Selecione a primeira linha em cada grupo GROUP BY? (em SO)
Detalhe menor: o operador SQL padrão para "não é igual" é
<>
. Use isso em vez de!=
(que também é aceito no Postgres).A única finalidade possível de ingressar na tabela
units
nesta consulta é verificar se existe uma ou mais linhas relacionadas. Sereports.unit_id
for vinculadounit.id
por chave estrangeira (como sugere a nomenclatura), a integridade referencial é garantida e você pode eliminarunit
completamente a tabela da consulta. Basta adicionar:unit_id IS NOT NULL
.