vanyahuk
@vanyahuk

Как правильно сформировать SQL запрос?

Есть 4 таблицы:

1) countries(id, name);
2) brands(id, name, country_id)
3) models(id, name, brand_id)
4) products(id, name, model_id)

В чем сложность запроса:
при выборке з таблицы products нужно фильтровать записи через whereIn
по model_id, brand_id, country_id

PS: записей в таблице products очень много ( около 1млн ) и запросы типа JOIN не предлагать, так как оно существенно влияет на производительность
  • Вопрос задан
  • 205 просмотров
Пригласить эксперта
Ответы на вопрос 4
ThunderCat
@ThunderCat
{PHP, MySql, HTML, JS, CSS} developer
записей в таблице products очень много ( около 1млн )

это не много, это нормально
и запросы типа JOIN не предлагать, так как оно существенно влияет на производительность

а этот бред вы как догадались сюда приплести? У вас наоборот с выходом из внутренних джоинов выборка по ид будет сокращаться, в итоге по таблице продуктс будет только джоин нужных ид(что аналогично выборке where in, только с меньшими ограничениями, например ордер и лимит). По этому сджойнте мелкие таблицы, получите с них модел_ид, и по нему уже джоин продкут.
Я бы денормализовал продуктс, внес бы еще брэнд_ид в него, но это так, мелочи.
Ответ написан
Комментировать
shurshur
@shurshur
Сисадмин, просто сисадмин...
А индексы по foreign key построены? Миллион не такое количество, чтобы join работал плохо.

Альтернативный путь один - денормализация. Надо все сущности добавить прямо в таблицу products отдельными колонками. Чтобы селектить только из этой таблицы.
Ответ написан
@immaculate
Программист-путешественник
Как уже сказали, вы не там смотрите. 1 млн — это немного, и запрос, даже с JOIN — очень простой, любая СУБД должна проглатывать его не поперхнувшись.

Скорее всего, вам надо тюнить настройки своей БД, там явно что-то не в порядке. Вот, например, статья для PostgreSQL: https://ruhighload.com/%D0%A2%D1%8E%D0%BD%D0%B8%D0...

Еще подобные статьи не раз публиковались на Хабрахабре.

Для начала надо показать здесь вывод EXPLAIN ANALYZE запроса (или аналог для вашей СУБД).
Ответ написан
Комментировать
@Vlad_fox
не хотите JOIN - можете так:
select p.id, p.name
from product p
where p.model_id in (
select m.id from models m
inner join brands b on b.id = m.brand_id
inner join countries c on c.id = b.country
where
m.brand_id in () -- фильтруете бренды
and b.country in () -- фильтруете страны
and m.id in () -- фильтруете модели
)

вложенный подзапрос возвратит набор отфильтрованных model_id.
для огромной (шучу) таблици product желателен индекс по model_id.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы