Вы можете добавить виртуальный столбец в таблицу, а затем включить этот столбец в индекс:
ALTER TABLE record ADD zero_dept_id AS (CASE department_id WHEN 0 THEN 0 END);
CREATE INDEX record_paritial_idx ON record (city_id, organization_id, zero_dept_id);
Если подумать, вам может понадобиться только индекс из одного столбца ниже, а не индекс из нескольких столбцоввыше.
CREATE INDEX record_paritial_idx ON record (zero_dept_id);
Тогда в вашем коде вместо r.department_id = 0
вы будете использовать r.zero_dept_id = 0
для использования нового индекса.
Нет гарантий, что это улучшит производительность вашего запроса, ноВы, конечно, можете попробовать.
Для многостолбцового индекса, который действительно удаляет все ненулевые записи Department_id, вам может понадобиться больше виртуальных столбцов:
ALTER TABLE record ADD zero_dept_id AS (CASE department_id WHEN 0 THEN 0 END);
ALTER TABLE record ADD zero_dept_city_id AS (CASE department_id WHEN 0 THEN city_id END);
ALTER TABLE record ADD zero_dept_org_id AS (CASE department_id WHEN 0 THEN organization_id END);
CREATE INDEX record_paritial_idx ON record (zero_dept_city_id, zero_dept_org_id, zero_dept_id);
Тогда в вашем коде выполнитесоответствующие замены, чтобы получить это:
r.zero_dept_city_id = t.city_id AND r.zero_dept_org_id = t.organization_id AND r.zero_dept_id = 0
В последнем варианте выше, вы могли бы удалить столбец zero_dept_id, так как два других виртуальных столбца будут иметь значения в индексе только тогда, когда идентификатор отдела равен нулю, в которомесли индекс станет следующим:
CREATE INDEX record_paritial_idx ON record (zero_dept_city_id, zero_dept_org_id);
, а предикат запроса будет:
r.zero_dept_city_id = t.city_id AND r.zero_dept_org_id = t.organization_id
с подразумеваемым предикатом department_id = 0
по нулевой отметке * виртуальные столбцы.