Производительность SQL ухудшается при добавлении предложения INNER JOIN в Postgres [закрыто]

У меня есть следующий запрос

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

производительность резко снижается. Теперь требуется 8,185 секунды для вывода 10 338 строк. Такое же ухудшение наблюдается, если я добавляю условие в предложение 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

Но добавление AND pft.concession_id IS NOT NULL в предложение WHERE снова снижает производительность до 7,938 секунды

-1
задан 28 April 2021 в 10:44

1 ответ

Наличие в запросе pft.concession_id НЕ НУЛЕВО не имеет значения, поскольку ] NULL значения не могут быть объединены. Они будут исключены естественным образом, потому что ПРИСОЕДИНЯЙТЕСЬ к концессии на счет пациента требует наличия соответствующей записи пациента и финансового перевода .

Простейший путь вперед - начать с EXPLAIN . PostgreSQL может тогда сказать вам, почему так долго возвращаются результаты:

EXPLAIN SELECT pri.* FROM patientreceiptitem pri ...
1
ответ дан 7 May 2021 в 17:42

Другие вопросы по тегам:

Похожие вопросы: