Индексирование динамического порядка по выражению - PullRequest
0 голосов
/ 23 ноября 2011

У меня есть SQL-запрос, который я выполняю в PostgreSQL, который выглядит следующим образом: (ActiveRecord сгенерирован, поэтому извиняюсь, если он не так оптимизирован, как мог бы быть)

SELECT DISTINCT items.id,
   CASE WHEN items.marker is not null
          THEN (items.rating - (educations.cards_done - items.marker))
        WHEN items.marker is null
          THEN 0 
   END AS order
FROM items
INNER JOIN educations ON educations.item_id = items.id 
WHERE items.active = true
ORDER BY 
   CASE WHEN items.marker is not null
          THEN (items.rating - (educations.cards_done - items.marker))
        WHEN items.marker is null
          THEN 0 
   END
LIMIT 10

Это так?можно иметь индекс по этому порядку с помощью оператора case в PostgreSQL?Если нет, есть ли другой способ ускорить этот запрос?Спасибо за любую помощь, вы можете предоставить!

1 Ответ

1 голос
/ 23 ноября 2011

Вы можете начать с оптимизации самого оператора 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, если индексы используются в вашем запросе.Если вы выберете большие части задействованных таблиц, последовательное сканирование все равно будет быстрее и индексы не будут использоваться.

...