Почему соединение плохое при рассмотрении масштабируемости?

Почему соединения плохо или "медленны". Я знаю, что слышал это более одного раза. Я нашел эту цитату

Проблема состоит в том, что медленно, особенно по очень большим данным устанавливает, и если они замедляют ваш сайт медленный. Это займет много времени получить все эти отдельные биты информацию с диска и поместить все вместе снова.

источник

Я всегда думал, что они были быстры, особенно при поиске ПК. Почему они "медленны"?

Ответ 1

Масштабируемость - это все о предварительных вычислениях, распределении или разделении повторяющейся работы до самого необходимого. Чтобы хорошо масштабироваться, вы не делаете ничего, в чем вы не нуждаетесь по объему, и вещи, которые вы действительно делаете, убедитесь, что выполняются максимально эффективно.

В этом контексте, конечно, присоединение к двум отдельным источникам данных является относительно медленным, по крайней мере, по сравнению с не присоединением к ним, потому что это работает, вам нужно жить в точке, где пользователь запрашивает это.

Но помните, что альтернатива больше не имеет двух отдельных частей данных; Вы должны поместить две разные точки данных в одну и ту же запись. Вы не можете объединить две разные части данных без каких-либо последствий, поэтому убедитесь, что вы понимаете компромисс.

Хорошая новость заключается в том, что современные реляционные базы данных хорошо подходят для соединений. Вы не должны думать о соединениях как о медленных с хорошей базой данных, используемой хорошо. База данных предоставляет несколько удобных для масштабирования способов создания необработанных объединений и их ускорения:

  • Присоединяйтесь к суррогатному ключу (столбец autonumer/identity), а не к естественному ключу. Это означает меньшее (и, следовательно, более быстрое) сравнение во время операции соединения
  • Индексы
  • Материализованные/индексированные представления (думайте об этом как о предварительно вычисленном соединении или управляемой отмене нормализации)
  • Вычисляемые столбцы. Вы можете использовать это для хеширования или иным образом предварительного вычисления ключевых столбцов объединения, так что теперь сложное сравнение для объединения теперь будет намного меньше и может быть предварительно проиндексировано.
  • Разделы таблиц (помогает с большими наборами данных, распределяя нагрузку на несколько дисков или ограничивая сканирование таблицы до сканирования разделов)
  • OLAP (предварительно вычисляет результаты некоторых видов запросов/объединений. Это не совсем так, но вы можете думать об этом как об общей денормализации)
  • Репликация, группы доступности, доставка журналов или другие механизмы, позволяющие нескольким серверам отвечать на запросы чтения для одной и той же базы данных и, таким образом, распределять рабочую нагрузку между несколькими серверами.

Я бы сказал, что основная причина, по которой реляционные базы данных вообще существуют, состоит в том, чтобы вы могли эффективно выполнять объединения *. Это, конечно, не просто для хранения структурированных данных (вы можете сделать это с помощью плоских файловых конструкций, таких как CSV или XML). Некоторые из перечисленных мною опций даже позволят вам полностью построить объединение заранее, поэтому результаты уже готовы до того, как вы выполните запрос - так же, как если бы вы денормализовали данные (правда, за счет более медленных операций записи).

Если у вас медленное соединение, вы, вероятно, неправильно используете свою базу данных.

Денормализацию следует проводить только после сбоя этих других методов. И единственный способ по-настоящему судить о "неудаче" - это установить значимые цели производительности и сравнить их с этими целями. Если вы еще не измерили, то слишком рано даже думать о денормализации.

* То есть существуют как объекты, отличные от простых наборов таблиц.Дополнительной причиной для реального rdbms является безопасный параллельный доступ.

Ответ 2

Соединения могут быть медленнее, чем избегать их путем де-нормализации, но если они используются правильно (присоединение к столбцам с соответствующими индексами и так далее) , они по своей сути медленны.

Де-нормализация является одним из многих методов оптимизации, которые вы можете рассмотреть, если ваша хорошо спроектированная схема базы данных демонстрирует проблемы с производительностью.

Ответ 3

В статье

говорится, что они медленны по сравнению с отсутствием объединений. это может быть достигнуто с денормализацией. поэтому существует компромисс между скоростью и нормализацией. не забывайте и о преждевременной оптимизации:)

Ответ 4

Прежде всего, реляционная база данных raison d'etre (причина существования) заключается в моделировании отношений между сущностями. Объединения - это просто механизмы, с помощью которых мы проходим эти отношения. Они, конечно же, имеют номинальную стоимость, но без объединений, действительно нет причин иметь реляционную базу данных.

В академическом мире мы узнаем о таких вещах, как различные нормальные формы (1-й, 2-й, 3-й, Boyce-Codd и т.д.), и мы узнаем о различных типах ключей (первичных, иностранных, альтернативных, уникальных и т.д. ) и как эти вещи подходят друг к другу для создания базы данных. И мы изучаем рудименты SQL, а также манипулируем как структурой, так и данными (DDL и DML).

В корпоративном мире многие из академических конструкций оказываются существенно менее жизнеспособными, чем мы верили. Прекрасным примером является понятие первичного ключа. Академически это атрибут (или набор атрибутов), который однозначно идентифицирует одну строку в таблице. Таким образом, во многих проблемных областях правильный академический первичный ключ представляет собой совокупность 3 или 4 атрибутов. Тем не менее, почти все в современном корпоративном мире используют автоматическое генерируемое последовательное целое в качестве первичного ключа таблицы. Зачем? Две причины. Первое заключается в том, что он делает модель намного чище, когда вы переносите FK по всему месту. Второй, и наиболее распространенный в этом вопросе, заключается в том, что получение данных через объединения происходит быстрее и эффективнее всего одного целого числа, чем на 4 столбцах varchar (как уже упоминалось несколькими людьми).

Позвольте немного углубиться в два конкретных подтипа баз данных реального мира. Первый тип - транзакционная база данных. Это основа для многих приложений электронной коммерции или управления контентом, ведущих современные сайты. С транзакционной БД вы сильно оптимизируете "пропускную способность транзакции". Большинство приложений для коммерции или контента должны балансировать производительность запросов (из определенных таблиц) со вставкой производительности (в других таблицах), хотя каждое приложение будет иметь свои собственные уникальные бизнес-решения для решения.

Второй тип базы данных реального мира - это база данных отчетов. Они используются почти исключительно для объединения бизнес-данных и создания значимых бизнес-отчетов. Они обычно формируются иначе, чем базы данных транзакций, в которых генерируются данные, и они высоко оптимизированы для скорости массовой загрузки данных (ETL) и производительности запросов с большими или сложными наборами данных.

В каждом случае разработчик или администратор базы данных должен тщательно балансировать как функциональные, так и эксплуатационные кривые, и есть множество улучшающих производительность трюков с обеих сторон уравнения. В Oracle вы можете сделать то, что называется "планом объяснения", чтобы вы могли видеть, как запрос обрабатывается и выполняется. Вы хотите максимально эффективно использовать индексы DB. Один действительно противный no-no - это поставить функцию в предложение where запроса. Всякий раз, когда вы это делаете, вы гарантируете, что Oracle не будет использовать какие-либо индексы в этом конкретном столбце, и вы, вероятно, увидите полное или частичное сканирование таблицы в плане объяснения. Это всего лишь один конкретный пример того, как может быть написан запрос, который заканчивается медленным, и он не имеет ничего общего с объединениями.

И хотя мы говорим о сканировании таблиц, они, очевидно, влияют на скорость запроса пропорционально размеру таблицы. Полное сканирование таблицы из 100 строк даже не заметно. Запустите тот же запрос в таблице со 100 миллионами строк, и вам нужно вернуться на следующей неделе для возврата.

Говорите о нормализации в течение минуты. Это еще одна в значительной степени положительная академическая тема, которая может стать слишком напряженной. Большую часть времени, когда мы говорим о нормализации, мы действительно имеем в виду устранение дублированных данных, помещая их в свою таблицу и мигрируя FK. Люди обычно пропускают всю зависимость, описанную 2NF и 3NF. И все же в крайнем случае, безусловно, возможно иметь идеальную базу данных BCNF, в которой огромный и полный зверь должен писать код, потому что он настолько нормализован.

Итак, где мы балансируем? Нет лучшего ответа. Все лучшие ответы, как правило, представляют собой некоторый компромисс между простотой обслуживания структуры, простотой обслуживания данных и простотой создания/обслуживания кода. В общем, чем меньше дублирование данных, тем лучше.

Так почему же соединения иногда замедляются? Иногда это плохой реляционный дизайн. Иногда это неэффективное индексирование. Иногда это проблема с объемом данных. Иногда это ужасно написанный запрос.

Извините за такой длинный ответ, но я чувствовал себя вынужденным предоставить более мясистый контекст вокруг моих комментариев, а не просто срывать ответ на 4 пули.

Ответ 5

Люди с базами данных размером с terrabyte по-прежнему используют объединения, если они могут заставить их работать с максимальной производительностью, так и вы.

Существует множество причин не деноминации. Во-первых, скорость выбора запросов не является единственной или даже главной проблемой с базами данных. Первоочередной задачей является целостность данных. Если вы денормализуете, тогда вам необходимо внедрить методы, чтобы денормализовать данные по мере изменения родительских данных. Поэтому предположим, что вы берете на хранение имя клиента во всех таблицах вместо того, чтобы присоединяться к клиентской таблице на client_Id. Теперь, когда имя клиента изменяется (вероятность 100% некоторых имен клиентов будет меняться со временем), теперь вам нужно обновить все дочерние записи, чтобы отразить это изменение. Если вы сделаете это с каскадным обновлением, и у вас будет миллион дочерних записей, насколько быстро вы предполагаете, что это будет и сколько пользователей будут испытывать проблемы с блокировкой и задержки в их работе, когда это произойдет? Кроме того, большинство людей, которые денормализуются, потому что "соединения медленны" недостаточно знают о базах данных, чтобы убедиться, что их целостность данных защищена и часто заканчиваются базами данных, которые имеют неиспользуемые данные, потому что целостность настолько плоха.

Денормализация - это сложный процесс, который требует глубокого понимания производительности и целостности базы данных, если это необходимо сделать правильно. Не пытайтесь денормализовать, если у вас нет такого опыта для персонала.

Совпадения довольно быстры, если вы делаете несколько вещей. Сначала используйте ключ precorgate, int join - почти alawys - самое быстрое соединение. Второй всегда индексирует внешний ключ. Используйте производные таблицы или условия соединения для создания меньшего набора данных для фильтрации. Если у вас есть большая очень сложная база данных, то нанимайте профессионального человека из базы данных, обладающего опытом в частичном разделении и управлении огромными базами данных. Существует множество методов для повышения производительности, не избавляясь от объединений.

Если вам просто нужны возможности запросов, то да, вы можете создать хранилище данных, которое может быть денормализировано и заполнено с помощью инструмента ETL (оптимизированного для скорости), а не ввода пользовательских данных.

Ответ 6

Соединения медленны, если

  • данные некорректно индексируются
  • результаты плохо фильтруются
  • запрос на соединение плохо написанный
  • наборы данных очень большие и сложные

Итак, истинно, чем больше ваши данные задают больше обработки, необходимой для запроса, но проверка и работа над первыми тремя параметрами вышеизложенного часто дает отличные результаты.

Ваш источник дает денормализацию в качестве опции. Это нормально только до тех пор, пока вы исчерпали лучшие альтернативы.

Ответ 7

Соединения могут быть медленными, если требуется сканировать большие части записей с каждой стороны.

Вот так:

SELECT  SUM(transaction)
FROM    customers
JOIN    accounts
ON      account_customer = customer_id

Даже если индекс определен в account_customer, все записи из последнего все еще нужно отсканировать.

Для списка запросов достойные оптимизаторы, вероятно, даже не рассмотрят путь доступа к индексу, вместо этого сделав HASH JOIN или MERGE JOIN.

Обратите внимание, что для такого запроса:

SELECT  SUM(transaction)
FROM    customers
JOIN    accounts
ON      account_customer = customer_id
WHERE   customer_last_name = 'Stellphlug'

соединение, скорее всего, будет быстрым: во-первых, индекс на customer_last_name будет использоваться для фильтрации всех Stellphlug (которые, конечно, не очень многочисленны), тогда будет сканирование индекса на account_customer для каждый Stellphlug, чтобы найти свои транзакции.

Несмотря на то, что это могут быть миллиарды записей в accounts и customers, на самом деле нужно будет отсканировать лишь немногие.

Ответ 8

Соединения требуют дополнительной обработки, так как они должны искать в большем количестве файлов и больше индексов для объединения данных. Однако "очень большие наборы данных" являются относительными. Что такое определение больших? Я делаю JOINs, я думаю, что это ссылка на большой набор результатов, а не на общий набор данных.

Большинство баз данных могут очень быстро обрабатывать запрос, который выбирает 5 записей из первичной таблицы и объединяет 5 записей из связанной таблицы для каждой записи (при условии, что имеются правильные индексы). Эти таблицы могут содержать сотни миллионов записей каждый или даже миллиарды.

Как только ваш результирующий набор начнет расти, все будет замедляться. Используя тот же пример, если в первичной таблице приводятся 100K-записи, тогда будет 500K "объединенных" записей, которые необходимо найти. Просто вытащить столько данных из базы данных с задержкой добавления.

Не избегайте JOINs, просто знайте, что вам может понадобиться оптимизировать/денормализовать, когда наборы данных становятся "очень большими".

Ответ 9

Также из статьи, которую вы цитировали:

Многие мега-масштабные веб-сайты с миллиардами записей, петабайт данных, многие тысячи одновременных пользователей и миллионы запросов в день делают используя схему осколков, а некоторые даже выступая за денормализацию как лучшая стратегия для уровень данных.

и

И если вы действительно большой вам, вероятно, не нужно беспокоиться об этом уровне сложности.

и

Это больше ошибок, чем наличие база данных выполняет всю эту работу, но вы способный делать масштаб за пределами того, что даже могут обрабатывать базы данных высшего уровня.

В статье обсуждаются мега-сайты, такие как Ebay. На этом уровне использования вам, скорее всего, придется подумать о чем-то отличном от обычного управления реляционными базами данных. Но в "нормальном" курсе бизнеса (приложения с тысячами пользователей и миллионах записей) эти более дорогие, более подверженные ошибкам подходы являются излишними.

Ответ 10

Соединения считаются противоположной силой масштабируемости, поскольку они, как правило, являются узким местом, и их нельзя легко распределить или сопоставить.

Ответ 11

Правильно спроектированные таблицы, содержащие правильные указания и правильно написанные запросы, не всегда медленны. Где бы вы ни слышали это:

Почему соединения плохо или "медленно"

не знает, о чем они говорят!!! Большинство подключений будут очень быстрыми. Если вам нужно присоединиться к множеству строк за один раз, вы можете сделать хит по сравнению с денормализованной таблицей, но это вернется к правильно разработанным таблицам, знайте, когда денормализовать и когда этого не сделать. в тяжелой системе отчетности, вырывают данные в денормализованных таблицах для отчетов или даже создают хранилище данных. В транзакционной тяжелой системе нормализовать таблицы.

Ответ 12

Joins are fast. Соединения должны рассматриваться как стандартная практика с правильно нормированной схемой базы данных. Объединение позволяет вам присоединиться к разрозненным группам данных значимым образом. Не бойтесь присоединиться.

Предостережение заключается в том, что вы должны понимать нормализацию, объединение и правильное использование индексов.

Остерегайтесь преждевременной оптимизации, поскольку отказ от числа всех проектов развития соответствует первому требованию. После того, как вы завершили проект, и вы поймете компромисс, вы можете нарушить правила, если вы можете это оправдать.

Верно, что производительность соединения ухудшается нелинейно по мере увеличения размера набора данных. Поэтому он не масштабируется так же хорошо, как одиночные таблицы, но он все еще имеет масштаб.

Также верно, что птица летает быстрее без каких-либо крыльев, но только прямо вниз.

Ответ 13

Количество создаваемых временных данных может быть огромным на основе объединений.

Например, одна база данных здесь на работе имела универсальную функцию поиска, где все поля были необязательными. Процедура поиска выполняла соединение на каждом столе до начала поиска. Это сработало хорошо в начале. Но теперь, когда основная таблица имеет более 10 миллионов строк... не так много. Поиски теперь занимают 30 минут и более.

Мне было поручено оптимизировать хранимую процедуру поиска.

Первое, что я сделал, - это поиск любого из полей основной таблицы, я сделал выбор только для таблицы temp только для этих полей. THEN, я присоединился ко всем таблицам с этой временной таблицей, прежде чем выполнять остальную часть поиска. Ищет, когда одно из основных полей таблицы занимает менее 10 секунд.

Если ни одно из основных полей таблицы не будет начато, я делаю аналогичную оптимизацию для других таблиц. Когда я закончил, поиск не займет больше 30 секунд, большинство из них менее 10.

Использование ЦП SQL-сервера также переместилось в WAY DOWN.

Ответ 14

Хотя объединение (предположительно, из-за нормализованного дизайна), очевидно, может быть медленнее для извлечения данных, чем чтение из одной таблицы, денормализованная база данных может быть медленной для операций создания/обновления данных, поскольку след всей транзакции не будет минимален.

В нормализованной базе данных часть данных будет жить только в одном месте, поэтому размер обновления для обновления будет минимальным. В денормализованной базе данных возможно, что один и тот же столбец из нескольких строк или между таблицами должен быть обновлен, что означает, что размер экрана будет больше, а вероятность блокировок и взаимоблокировок может увеличиться.

Ответ 15

Ну, да, выбирая строки из одной денормализованной таблицы (предполагая приличные индексы для вашего запроса), может быть быстрее, если выбирать строки, построенные из объединения нескольких таблиц, особенно если соединения не имеют эффективных индексов.

Приведенные в статье примеры - Flickr и eBay - являются исключительными случаями ИМО, поэтому имеют (и заслуживают) исключительные ответы. Автор конкретно указывает на отсутствие RI и степень дублирования данных в этой статье.

Большинство приложений - опять же, ИМО - выигрывают от проверки и уменьшения дублирования, предоставляемого РСУБД.

Ответ 16

Они могут быть медленными, если они выполняются небрежно. Например, если вы выполните "select *" в соединении, вы, вероятно, займетесь временем, чтобы вернуть материал. Однако, если вы тщательно выбираете, какие столбцы должны возвращаться из каждой таблицы, и с соответствующими индексами на месте, проблем не должно быть.