Вы можете начать с оптимизации самого оператора CASE.2-й WHEN
является избыточным.Может быть только два случая (NULL
и NOT NULL
).Упрощение:
CASE WHEN items.marker is not null
THEN ((items.rating + items.marker) - educations.cards_done)
ELSE 0 END
Что касается индексирование , я не знаю, как использовать значения из более чем одной таблицы в индексе.Для этого вам придется использовать материализованное представление или избыточный столбец в одной из таблиц, который может обновляться триггерами.Я бы подумал только об этом, если производительность ORDER
очень важна и используемые таблицы в основном читаются и редко записываются.
Я предполагаю, что у вас уже есть индексы educations.item_id
И items.id
?(Первичный ключ - это автоматический индекс, внешний ключ - , а не .)
В зависимости от процента элементов с active = true
может помочь частичный индекс на items
.Для этого активные элементы должны быть в меньшинстве.
CREATE INDEX foo_idx ON items(id) WHERE active;
Тест с EXPLAIN ANALYZE
, если индексы используются в вашем запросе.Если вы выберете большие части задействованных таблиц, последовательное сканирование все равно будет быстрее и индексы не будут использоваться.