Являются ли запросы JOIN быстрее, чем несколько запросов? (Вы запускаете свой основной запрос, а затем запускаете множество других SELECT на основе результатов вашего основного запроса)
Я спрашиваю, потому что присоединение к ним усложнит ОЧЕНЬ дизайн моего приложения
Если они быстрее, может ли кто-нибудь приблизительно приблизиться к тому, насколько? Если это в 1,5 раза, мне все равно, но если это в 10 раз, я думаю, что да.
mysql
database
join
query-optimization
Томас Бонини
источник
источник
Ответы:
Это слишком расплывчато, чтобы дать вам ответ, соответствующий вашему конкретному случаю. Это зависит от многих вещей. Джефф Этвуд (основатель этого сайта) на самом деле написал об этом . По большей части, тем не менее, если у вас есть правильные индексы и вы правильно выполняете свои СОЕДИНЕНИЯ, обычно будет быстрее выполнить 1 поездку, чем несколько.
источник
Для внутренних объединений единственный запрос имеет смысл, поскольку вы получаете только совпадающие строки. Для левых объединений несколько запросов намного лучше ... посмотрите на следующий тест, который я сделал:
Один запрос с 5 объединениями
запрос: 8,074508 секунд
размер результата: 2268000
5 запросов подряд
время комбинированного запроса: 0,00262 секунды
размер результата: 165 (6 + 50 + 7 + 12 + 90)
,
Обратите внимание, что мы получаем одинаковые результаты в обоих случаях (6 х 50 х 7 х 12 х 90 = 2268000)
левые соединения используют экспоненциально больше памяти с избыточными данными.
Ограничение памяти может быть не таким плохим, если вы объединяете только две таблицы, но, как правило, три или более, и это становится полезным для разных запросов.
Как примечание, мой сервер MySQL находится рядом с моим сервером приложений ... поэтому время подключения незначительно. Если ваше время соединения в секундах, то, возможно, есть преимущество
Фрэнк
источник
Этот вопрос старый, но в нем отсутствуют некоторые критерии. Я сравнил JOIN с его 2 конкурентами:
WHERE IN(...)
или эквивалентныйРезультат ясен: на MySQL
JOIN
все намного быстрее. N + 1 запросы могут резко снизить производительность приложения:То есть, если вы не выберете много записей, которые указывают на очень небольшое количество отдельных, иностранных записей. Вот эталон для крайнего случая:
Это вряд ли произойдет в типичном приложении, если только вы не присоединяетесь к отношению-ко-многим, в этом случае внешний ключ находится в другой таблице, и вы дублируете данные основной таблицы много раз.
вынос:
JOIN
Смотрите мою статью на Medium для получения дополнительной информации.
источник
На самом деле я пришел к этому вопросу в поисках ответа сам, и после прочтения данных ответов я могу только согласиться с тем, что лучший способ сравнить производительность запросов к БД - это получить реальные цифры, поскольку необходимо учитывать только много переменных. НО, я также думаю, что сравнение чисел между ними не приносит пользы почти во всех случаях. Я имею в виду, что цифры всегда следует сравнивать с приемлемым числом, а не сравнивать друг с другом.
Я могу понять, если один способ запроса занимает, скажем, 0,02 секунды, а другой - 20 секунд, это огромная разница. Но что, если один способ запроса занимает 0,0000000002 секунды, а другой - 0,0000002 секунды? В обоих случаях один способ колоссально в 1000 раз быстрее, чем другой, но действительно ли он все еще «колоссален» во втором случае?
Итог, как я лично это вижу: если он работает хорошо, выбирайте простое решение.
источник
Провел быстрый тест, выбрав одну строку из таблицы строк 50000 и соединившись с одной строкой из таблицы строк 100000. В основном выглядело так:
против
Метод «два выбора» занял 3,7 секунды для 50 000 операций чтения, тогда как на моем медленном домашнем компьютере JOIN занял 2,0 секунды. INNER JOIN и LEFT JOIN ничего не изменили. Выборка нескольких строк (например, с использованием IN SET) дала аналогичные результаты.
источник
Реальный вопрос: есть ли у этих записей отношение один к одному или отношение один ко многим ?
Ответ TLDR:
Если один на один, используйте
JOIN
утверждение.Если один ко многим, используйте один (или много)
SELECT
операторов с оптимизацией кода на стороне сервера.Почему и как использовать SELECT для оптимизации
SELECT
Использование (с несколькими запросами вместо объединений) для большой группы записей на основе отношения «один ко многим» обеспечивает оптимальную эффективность, поскольку в случае сJOIN
проблемой экспоненциальной утечки памяти. Соберите все данные, а затем используйте язык сценариев на стороне сервера, чтобы разобраться в них:Полученные результаты:
Здесь я получаю все записи в одном операторе выбора. Это лучше, чем
JOIN
, что бы получить небольшую группу этих записей, по одной, как подкомпонент другого запроса. Затем я анализирую его с помощью серверного кода, который выглядит примерно так ...Когда не использовать JOIN для оптимизации
JOIN
большая группа записей, основанная на взаимно-однозначных отношениях с одной записью, обеспечивает оптимальную эффективность по сравнению с множествомSELECT
операторов один за другим, которые просто получают следующий тип записи.Но
JOIN
неэффективно при получении записей с отношением один ко многим.Пример: Блоги базы данных имеют 3 таблицы интереса: Blogpost, Tag и Comment.
Если есть 1 запись блога, 2 тега и 2 комментария, вы получите следующие результаты:
Обратите внимание, как дублируется каждая запись. Итак, 2 комментария и 2 тега - это 4 строки. Что если у нас есть 4 комментария и 4 тега? Вы не получаете 8 строк - вы получаете 16 строк:
Добавьте больше таблиц, больше записей и т. Д., И проблема быстро раздуется до сотен строк, которые заполнены в основном избыточными данными.
Сколько стоят эти дубликаты? Память (в SQL-сервере и коде, который пытается удалить дубликаты) и сетевые ресурсы (между SQL-сервером и вашим сервером кода).
Источник: https://dev.mysql.com/doc/refman/8.0/en/nested-join-optimization.html ; https://dev.mysql.com/doc/workbench/en/wb-relationship-tools.html
источник
Создайте как отдельные запросы, так и объединения, а затем оцените каждый из них - ничто не поможет больше, чем реальные цифры.
Тогда еще лучше - добавьте «EXPLAIN» в начало каждого запроса. Это скажет вам, сколько подзапросов MySQL использует для ответа на ваш запрос данных, и сколько строк проверено для каждого запроса.
источник
В зависимости от сложности базы данных по сравнению со сложностью разработчика, может быть проще выполнять много вызовов SELECT.
Попробуйте запустить некоторую статистику базы данных как для JOIN, так и для нескольких SELECTS. Посмотрите, если в вашей среде JOIN быстрее / медленнее, чем SELECT.
Опять же, если изменение его на JOIN будет означать дополнительный день / неделю / месяц работы разработчика, я бы придерживался нескольких SELECT
Ура,
BLT
источник
По своему опыту я обнаружил, что обычно несколько запросов выполняется быстрее, особенно при получении больших наборов данных.
При взаимодействии с базой данных из другого приложения, такого как PHP, существует аргумент одной поездки на сервер из-за многих.
Существуют и другие способы ограничить количество обращений к серверу и, тем не менее, выполнить несколько запросов, которые часто не только быстрее, но и облегчают чтение приложения - например, mysqli_multi_query.
Я не новичок в том, что касается SQL, я думаю, что разработчики, особенно юниоры, склонны тратить много времени, пытаясь написать очень умные объединения, потому что они выглядят умными, тогда как на самом деле есть умные способы извлечения данных, которые выглядят просто.
Последний абзац был личным мнением, но я надеюсь, что это поможет. Я согласен с другими, хотя, кто говорит, что вы должны ориентироваться. Ни один из подходов не является серебряной пулей.
источник
Следует ли вам использовать объединение, в первую очередь, имеет ли смысл объединение . Только на этом этапе производительность даже нужно учитывать, так как почти во всех других случаях производительность будет значительно хуже .
Различия в производительности во многом будут зависеть от того, насколько связана информация, к которой вы обращаетесь. Объединения работают и работают быстро, когда данные связаны, и вы правильно индексируете данные, но они часто приводят к некоторой избыточности, а иногда и к большему количеству результатов, чем необходимо. И если ваши наборы данных не связаны напрямую, их привязка к одному запросу приведет к тому, что называется декартовым произведением (в основном, всеми возможными комбинациями строк), что почти никогда не является тем, что вам нужно.
Это часто вызвано отношениями «многие к одному». Например, в ответе HoldOffHunger упоминается один запрос для сообщений, тегов и комментариев. Комментарии связаны с постом, как и теги ... но теги не имеют отношения к комментариям.
В этом случае однозначно лучше, чтобы это было как минимум два отдельных запроса. Если вы попытаетесь объединить теги и комментарии, поскольку между ними нет прямой связи, вы получите все возможные комбинации тегов и комментариев.
many * many == manymany
, Кроме того, поскольку посты и теги не связаны, вы можете выполнять эти два запроса параллельно, что приведет к потенциальной выгоде.Давайте рассмотрим другой сценарий: вы хотите, чтобы комментарии, прикрепленные к сообщению, и контактная информация комментаторов.
Это где вы должны рассмотреть вопрос о присоединении. Помимо гораздо более естественного запроса, большинство систем баз данных (включая MySQL) имеют много умных людей, которые так же много работают над оптимизацией запросов. Для отдельных запросов, поскольку каждый запрос зависит от результатов предыдущего, запросы не могут выполняться параллельно, и общее время становится не только фактическим временем выполнения запросов, но и временем, потраченным на выборку результатов, просеивание через них для идентификаторов для следующего запроса, связывания строк и т. д.
источник
Будет ли это быстрее с точки зрения пропускной способности? Наверное. Но он также потенциально блокирует больше объектов базы данных одновременно (в зависимости от вашей базы данных и вашей схемы) и тем самым уменьшает параллелизм. По моему опыту, людей часто вводят в заблуждение аргументом «меньшее количество обращений к базе данных», когда в действительности в большинстве систем OLTP, где база данных находится в одной и той же локальной сети, реальным узким местом является редко сеть.
источник
Вот ссылка со 100 полезными запросами, они протестированы в базе данных Oracle, но помните, что SQL - это стандарт, который отличается от Oracle, MS SQL Server, MySQL и других баз данных SQL-диалектом:
http://javaforlearn.com/100-sql-queries-learn/
источник
Есть несколько факторов, которые означают, что нет двоичного ответа. Вопрос о том, что лучше для производительности, зависит от вашей среды. Кстати, если ваш одиночный выбор с идентификатором не является вторым, что-то может быть не так с вашей конфигурацией.
Реальный вопрос - как вы хотите получить доступ к данным? Single выбирает поддержку позднего связывания. Например, если вам нужна только информация о сотруднике, вы можете выбрать ее из таблицы «Сотрудники». Отношения внешнего ключа могут использоваться для извлечения связанных ресурсов позднее и по мере необходимости. У селекторов уже будет ключ для указания, поэтому они должны быть очень быстрыми, и вам нужно только получить то, что вам нужно. Сетевая задержка всегда должна учитываться.
Объединения будут извлекать все данные одновременно. Если вы создаете отчет или заполняете сетку, это может быть именно тем, что вам нужно. Скомпилированные и оптомизированные объединения просто будут быстрее, чем одиночные выборки в этом сценарии. Помните, что специальные объединения могут быть не такими быстрыми - вы должны скомпилировать их (в сохраненный процесс). Скорость ответа зависит от плана выполнения, который точно определяет, какие шаги СУБД предпринимает для извлечения данных.
источник
Да, один запрос с использованием JOINS будет быстрее. Хотя, не зная взаимосвязей запрашиваемых таблиц, размера набора данных или расположения первичных ключей, почти невозможно сказать, насколько быстрее.
Почему бы не проверить оба сценария, тогда вы наверняка узнаете ...
источник