Использование OR
в запросах SQL обычно приводит к снижению производительности.
Это потому, что & ndash; отличается от AND
& ndash; это не ограничивает, но увеличивает количество строк в результате запроса. С AND
вы можете использовать сканирование индекса для одной части условия и дополнительно ограничить результирующий набор фильтром для второго условия. Это невозможно с OR
.
Таким образом, PostgreSQL делает единственное, что осталось: он вычисляет все соединение, а затем отфильтровывает все строки, которые не соответствуют условию. Конечно, это очень неэффективно, когда вы объединяете три таблицы (я не учел внешнее соединение).
Предполагая, что все столбцы с именем id
являются первичными ключами, вы можете переписать запрос следующим образом:
SELECT count(*) FROM
(SELECT _pcn.id
FROM patientchartnote _pcn
INNER JOIN appointment _appt
ON _appt.id = _pcn.appointment_id
INNER JOIN patient _pt
ON _pt.id = _appt.patient_id
LEFT OUTER JOIN person _ps
ON _ps.id = _pt.appuser_id
WHERE _pcn.active = true
AND _pt.active = true
AND _appt.datecomplete IS NULL
AND _pcn.title IS NOT NULL
AND _pcn.title <> ''
AND _pt.assigned_to_user_id = '136964'
UNION
SELECT _pcn.id
FROM patientchartnote _pcn
INNER JOIN appointment _appt
ON _appt.id = _pcn.appointment_id
INNER JOIN patient _pt
ON _pt.id = _appt.patient_id
LEFT OUTER JOIN person _ps
ON _ps.id = _pt.appuser_id
WHERE _pcn.active = true
AND _pt.active = true
AND _appt.datecomplete IS NULL
AND _pcn.title IS NOT NULL
AND _pcn.title <> ''
AND _pcn.createdby_id = '136964'
) q;
Несмотря на то, что запрос выполняется дважды, индексы можно использовать для ранней фильтрации всех строк, кроме нескольких, поэтому этот запрос должен работать лучше.