Запрет на join? Оптимизированная выборка из связи многие-ко-многим без join с параметрами из линкованных таблиц?

На многих конференциях программисты из крупных компаний говорят, что у них лежит запрет на использование join, здесь я понимаю, что на больших данных - это затратная операция, но как, например, взять стандартный пример, у меня есть книги и их авторы со связью многие ко многим. Будем считать, что в таблицах "большое количество записей". Как сделать оптимизированную выборку, если нужно в условии использовать параметры из двух таблиц (WHERE book.param = 1 AND author.param = 2). Да, здесь, например, приходит идея использования IN(ids), но здесь опять же в одной из таблиц может быть большое количество ids выбранных по параметру, и на мой взгляд это тоже не очень, (плюс думаю есть какое-то ограничение по количеству ids)? Как это сделать более правильно?
  • Вопрос задан
  • 769 просмотров
Пригласить эксперта
Ответы на вопрос 2
ruFelix
@ruFelix
Предсказание будущего по руке, таро, кофе.
Они так говорят, потому что:
1) Если вы везде используете JOIN то на большом проекте у вас перестаёт работать кеш встроенный в БД, т.к. insert или update хотя бы в одну из таблиц участниц join сбросит кеш всего запроса, а на больших проектах изменения данных идут постоянным потоком.
2) JOIN делает жётские связи на уровне данных, это хоронит возможность оптимизации на уровне архитектуры приложения. Когда таблицы не связанны внешними ключами и запросами то мы можем перенести любую таблицу, в другую БД оптимизированную для нужных типов запросов, написать например на Си отдельный сервис/демон для этих данных. При этом нам надо будет переписать только одну сущность в приложении. В случае с разрешёнными JOIN может выясниться что переписать надо вообще всё.
3) Существует популярный подход переваривания больших нагрузок/данных это шардинг, т.е. раскидывание диапазонов данных по разным серверам, это когда первые 10 миллионов записей лежат на одном сервере а вторые на другом, join в этом случае сделать нельзя.
4) Нормализация, полностью нормализованная БД самая медленна(т.к. куча JOIN, каждый из них это умножение двух матриц), но зато самая компактная, полностью не нормализованная БД самая быстрая (так как всё берём одним простым запросом), но очень жирная и неприемлемо сложная в работе.

Ваш пример очень абстрактен, если про него ясно только, что данных очень много и не известно кто и в каких условиях будет с этим работать, но скорость ответа важна, а количество запросов будет большими. (Например это API к которому сторонние люди будут писать приложения и потенциально рекламировать эти приложения по ТВ)
То например так:
1) Запросом c JOIN скормить данные этих двух таблиц в поисковый индекс на sphinxsearch
2) Делаем запрос с параметрами book.param = 1 AND author.param = 2 поисковому индексу сфинкса, он возвращает нам PK ID нужных сущностей
3) Делаем SELECT * FROM t WHERE id in(1,2,3..N)

Таким образом мы получаем сложную и тяжёлую фоновую индексацию, но очень быстрые и отъедающие крохи ресурсов сервера запросы в онлайне. Из минусов сильно усложняем архитектуру, а соответственно написание, отладка и поддержка кода становятся намного дольше, а количество людей которые могут это делать намного меньше, что в свою очередь является серьёзной проблемой но другого уровня.
Ответ написан
Комментировать
@doktr
Data Scientist
Если поля, по которым производится JOIN, имеют индексы, то запрос будет идти гораздо быстрее, чем без них, так что нужно смотреть индивидуально. Если индексов нет, то в плане выполнения, скорее всего, будет FULL SCAN и итоговое время будет пропорционально произведению количества строк в двух соединяемых таблицах - O(M*N).
Ответ написан
Комментировать
Ваш ответ на вопрос

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

Войти через центр авторизации
Похожие вопросы