Получить только нужные вам столбцы
Первая проблема с запросом состоит в том, что SELECT *
возвращает все столбцы из всех таблиц , включенных в запрос.Это означает, что возвращаются значения в критериях JOIN по обе стороны от оценки.Лучше выписать фактические столбцы, которые вам нужны, потому что у всех трех перечисленных вами столбцов есть столбец id
, что усложняет поиск правильного значения, если только не используется порядковый номер (не очень хорошая практика - измените положение, поиск данных - это не то, что нужнодолжно быть).
Использование псевдонимов таблицы минимизирует то, что вам нужно использовать для ссылки на конкретную таблицу:
SELECT a.article
FROM ARTICLES a
JOIN RESULTS r ON r.article_id = a.id
JOIN ITEMS i ON i.id = r.item_id
Индексирование
Индексирование внешних ключей - что выиспользование критерия для соединения JOIN должно быть вторым в списке после первичного ключа таблицы.
Затем необходимо периодически запускать команду ANALYZE , поскольку статистика ...
... не обновляется автоматически при изменении содержимого базы данных.Если содержимое базы данных существенно изменяется или если изменяется схема базы данных, следует рассмотреть возможность повторного запуска команды ANALYZE для обновления статистики.
Эти статистические данные используются оптимизатором для своего запроса.решение, наряду с наличием индексов.
ИЛИ печально сказываются на производительности
Вы можете попробовать переписать запрос, чтобы он не использовал ИЛИ с UNION:
SELECT a.article
FROM ARTICLES a
JOIN RESULTS r ON r.article_id = a.id
JOIN ITEMS i ON i.id = r.item_id
WHERE i.foodtype = 'vegetable'
UNION
SELECT a.article
FROM ARTICLES a
JOIN RESULTS r ON r.article_id = a.id
JOIN ITEMS i ON i.id = r.item_id
WHERE i.food IN ('orange', 'grape')
Имейте в виду, что UNION
медленнее, чем UNION ALL
, поскольку UNION
удаляет дубликаты.UNION ALL
быстрее, потому что не удаляет дубликаты.