У меня есть несколько таблиц, которые более или менее похожи на это (я буду использовать более простой домен, поэтому объяснение будет более ясным):
Trades
----------
ID
Seller_ID
Trade_Date
Sellers
-------
ID
Department_ID
И я хочу получить последнюю сделку, сделанную каждым отделом,Запрос выглядит примерно так:
SELECT Department_ID, MAX(Trade_Date) FROM
Trades, Sellers
WHERE Trades.Seller_ID = Sellers.ID
GROUP BY Sellers.Department_ID
Таблица Trades имеет индекс на дату, поэтому его можно использовать для ускорения запросов, но я заметил, что запрос выполняется для некоторых отделов быстро (жесткое кодированиеid) и очень медленный для других.
Я сделал вывод, что это происходит из-за огромной разницы в объеме сделок по каждому отделу.База данных выполняет последовательное сканирование отсортированного индекса, чтобы получить первое вхождение, и те отделы, которые давно осуществили свои последние продажи, должны будут пойти очень далеко в индексе.
Мое текущее решение - сохранитьпоследний запрос приводит к появлению вспомогательной таблицы и делает новые запросы инкрементальными (фильтрация по самой последней дате, которая уже была во вспомогательной таблице).Это решает проблему, так как запрос выполняется очень часто, и теперь сканирование индекса просто должно учитывать количество сделок в несколько секунд.
Но я думаю, что для этого должно быть более элегантное решение.Я знаю, что если бы агрегация была сделана Продавцом, а не Департаментом, составной индекс определенно помог бы, но я не думаю, что это позволяет строить индексы, которые порождают разные таблицы ...