У меня есть следующий запрос
SELECT pri.*
FROM patientreceiptitem pri
JOIN patientfinancialtransaction_patientreceiptitem pp ON pri.id = pp.receiptitems_id
JOIN patientfinancialtransaction pft ON pp.patientfinancialtransaction_id = pft.id
WHERE pri.createtime >= '2020-03-01'
AND pri.createtime < '2020-04-01'
Он выполняется за 1,79 секунды и дает на выходе 111 793 строки
Однако, когда я добавляю условие, которое является более ограничительным, как показано ниже:
JOIN patientbillconcession pbc ON pbc.id = pft.concession_id
производительность резко ухудшается. Теперь для вывода 10 338 строк требуется 8,185 секунды. Такое же ухудшение наблюдается, если я добавляю условие в предложение JOIN для таблицы pft
:
SELECT pri.*
FROM patientreceiptitem pri
JOIN patientfinancialtransaction_patientreceiptitem pp ON pri.id = pp.receiptitems_id
JOIN patientfinancialtransaction pft ON pp.patientfinancialtransaction_id = pft.id
AND pft.concession_id IS NOT NULL
WHERE pri.createtime >= '2020-03-01'
AND pri.createtime < '2020-04-01'
concession_id
индексируется в таблице pft
.
Любые указатели были бы хороши.
Я использую Postgres 12 в Arch Linux. Мой клиент - DBeaver 7.3.2.
Обновление 1:
Я обнаружил, что изменение следующего параметра на LEFT JOIN завершает запрос за 1,914 секунды:
LEFT JOIN Patientbillconcession pbc ON pbc.id = pft.concession_id
Но добавление И pft.concession_id IS NOT NULL
в предложение WHERE снова снижает производительность до 7,938 секунд
Наличие в запросе pft.concession_id НЕ НУЛЕВО
не имеет значения, поскольку ] NULL
значения не могут быть объединены. Они будут исключены естественным образом, потому что ПРИСОЕДИНЯЙТЕСЬ к концессии на счет пациента
требует наличия соответствующей записи пациента и финансового перевода
.
Простейший путь вперед - начать с EXPLAIN
. PostgreSQL может тогда сказать вам, почему так долго возвращаются результаты:
EXPLAIN SELECT pri.* FROM patientreceiptitem pri ...