Когда и почему соединения базы данных являются дорогими?

Как будто вы пытаетесь получить доступ к объекту, который является null. Рассмотрим ниже пример:

TypeA objA;

. В это время вы только что объявили этот объект, но не инициализировали или не инициализировали. И всякий раз, когда вы пытаетесь получить доступ к каким-либо свойствам или методам в нем, он будет генерировать NullPointerException, что имеет смысл.

См. Также этот пример:

String a = null;
System.out.println(a.toString()); // NullPointerException will be thrown
343
задан Community 23 May 2017 в 02:34
поделиться

7 ответов

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

Chris Date, который в компании с доктором Ted Codd был исходным сторонником реляционной модели данных, закончился терпение к дезинформированным аргументам против нормализации и систематически уничтожал их использующий научный метод: он получил большие базы данных и протестировал эти утверждения.

Я думаю, что он описал его в Записях Реляционной базы данных 1988-1991, но эта книга была позже прокручена в выпуск шесть из Введения в Системы баз данных, которое является категорическим текстом на теории баз данных и дизайне в его восьмом выпуске, как я пишу и вероятно оставаться в печати в течение будущих десятилетий. Chris Date был экспертом в этом поле, когда большинство из нас все еще обтекало босиком.

Он нашел что:

  • Некоторые из них содержат для особых случаев
  • Всем им не удается окупиться для общего использования
  • Все они значительно хуже для других особых случаев

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

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

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

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

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

  • Существует меньше чем 200 строк в отношении (в этом случае, сканирование будет более дешевым),
  • Нет никаких подходящих индексов на объединяющих столбцах (если это значимо для присоединения на этих столбцах затем, почему они не индексированы? зафиксируйте его),
  • Приведение типа требуется, прежде чем столбцы могут быть сравнены (WTF?! зафиксируйте его или пойдите домой), СМ. ПРИМЕЧАНИЯ КОНЦА ДЛЯ ПРОБЛЕМЫ ADO.NET
  • Одним из аргументов сравнения является выражение (никакой индекс)

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

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

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

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

Я также хотел бы ответить на

Соединения являются просто декартовыми произведениями с некоторым блеском для губ

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

Единственным путем Вы будете когда-либо добираться, оптимизатор для создания декартова произведения не должен предоставлять предикат: SELECT * FROM A,B


Примечания


David Aldridge предоставляет некоторую важную дополнительную информацию.

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

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

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


"Яйца", возможно, были бестактны. Меня просят быть менее надменным и напомнил, что математика не лежит. Это верно, но не все последствия математических моделей должен обязательно быть взят буквально. Квадратные корни отрицательных чисел очень удобны, если Вы тщательно стараетесь не исследовать их нелепость (игра слов там) и делаете чертовски уверенными, что Вы отменяете их всех, прежде чем Вы попытаетесь интерпретировать свое уравнение.

Причина, что я ответил так жестоко, состояла в том, что заявление, как сформулировано говорит об этом

Соединения являются декартовыми произведениями...

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

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


Сокращение для выбора стратегии соединения сканирования таблицы может варьироваться между механизмами базы данных. Это затронуто многими решениями реализации, такими как коэффициент заполнения древовидного узла, размер значения ключа и тонкость алгоритма, но вообще говоря высокоэффективная индексация имеет время выполнения k, регистрируют n + c. Термин C является фиксированными издержками, главным образом сделанными из времени установки, и форма кривой означает, что Вы не получаете выплату (по сравнению с линейным поиском), пока n не находится в сотнях.


Иногда денормализация является хорошей идеей

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

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

Правильно разработанное хранилище данных периодически производится объемным преобразованием из нормализованной системы обработки транзакций. Это разделение операций и создания отчетов о базах данных имеет очень желательный эффект устранения столкновения между OLTP и OLAP (оперативная обработка транзакций т.е. ввод данных, и оперативная аналитическая обработка т.е. создание отчетов).

Важный момент здесь - то, что кроме периодических обновлений, хранилище данных только для чтения. Это представляет спорный вопрос аномалий обновления.

Не делайте ошибку денормализовывания Вашей базы данных OLTP (база данных, на которой ввод данных происходит). Это могло бы быть быстрее для тарификации выполнений, но если Вы сделаете это, то Вы получите аномалии обновления. Когда-нибудь попробованный, чтобы заставить Reader's Digest прекращать отправлять Вам материал?

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


Проблема ADO.NET с несоответствиями типов

Предположим, что у Вас есть таблица SQL Server, содержащая индексированный столбец типа varchar, и Вы используете AddWithValue для передачи параметра, ограничивающего запрос на этом столбце. Строки C# являются Unicode, таким образом, выведенный тип параметра будет NVARCHAR, который не соответствует VARCHAR.

VARCHAR к NVARCHAR является расширяющимся преобразованием, таким образом, это происходит неявно - но попрощайтесь с индексацией и удачей, удающейся почему.


"Считайте дисковые хиты" (Rick James)

Если все кэшируется в RAM, JOINs являются довольно дешевыми. Таким образом, нормализация не имеет большой потери производительности.

Если "нормализованная" схема вызывает JOINs поражать диск много, но эквивалентную "денормализованную" схему не должно было бы поражать диск, затем денормализация выигрывает соревнование по производительности.

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

458
ответ дан 20 revs, 6 users 88% 23 November 2019 в 00:33
поделиться

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

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

  • хэширование А, в котором объемные данные являются equijoined, является очень дешевым действительно, и стоимость только становится значительной, если хеш-таблица не может кэшироваться в памяти. Никакой индекс не требуется. Equi-разделение между наборами данных, к которым присоединяются, может быть большой справкой.
  • стоимость слияния вида управляется стоимостью вида, а не слияния - основанный на индексе метод доступа может фактически устранить стоимость вида.
  • стоимость соединения вложенного цикла на индексе управляется высотой индекса B-дерева и доступом самого блока таблицы. Это быстро, но не подходит для объемных соединений.
  • соединение вложенного цикла А на основе кластера является намного более дешевым с меньшим количеством логического IO'S, необходимым на строку соединения - если объединяемые таблицы находятся оба в том же кластере затем, соединение становится очень дешевым через соразмещение строк, к которым присоединяются.

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

45
ответ дан David Aldridge 23 November 2019 в 00:33
поделиться

Я думаю, что целый вопрос основан на ложной посылке. Соединения на больших таблицах не обязательно дороги. На самом деле делающие соединения эффективно являются одной из главных причин, реляционные базы данных существуют вообще. Соединения на большом наборы часто являются дорогими, но очень редко делают Вы хотите присоединиться ко всему содержанию большой таблицы A со всем содержанием большой таблицы B. Вместо этого Вы пишете запрос, таким образом, что только важные строки из каждой таблицы используются, и фактический набор, сохраненный соединением, остается меньшим.

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

, Когда сделано правильно, соединения обычно лучший способ , чтобы выдержать сравнение, объединиться, или фильтр на больших объемах данных.

27
ответ дан Joel Coehoorn 23 November 2019 в 00:33
поделиться

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

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

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

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

О единственных издержках с соединением прибывает из выяснения строк соответствия. SQL-сервер использует 3 различных типов соединений, главным образом на основе размеров набора данных, для нахождения соответствия строкам. Если оптимизатор выбирает неправильный тип соединения (из-за неточной статистики, несоответствующих индексов, или просто ошибки оптимизатора или пограничного случая), это может решительно влиять на времена запроса.

  • соединение цикла А является довольно дешевым для (по крайней мере 1) небольшой набор данных.
  • слияние А требует своего рода обоих наборов данных сначала. Если Вы присоединяетесь на индексированном столбце, тем не менее, тогда, индекс уже отсортирован, и никакая дальнейшая работа не должна быть сделана. Иначе существует некоторый ЦП и память наверху в сортировке.
  • хэширование требует обеих памятей (для хранения хеш-таблицы) и ЦП (для создания хеша). Снова, это довольно быстро относительно дискового ввода-вывода. Однако , если существует недостаточно RAM для хранения хеш-таблицы, SQL-сервер будет использовать tempdb, чтобы сохранить части хеш-таблицы и найденных строк, и затем обработать только части хеш-таблицы за один раз. Как со всеми вещами диск, это довольно медленно.

В оптимальном случае, они не вызывают дискового ввода-вывода - и так незначительны с точки зрения производительности.

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

, Так как время запроса обычно во власти затрат ввода-вывода, и размер Ваших данных не изменяется (минус некоторая очень миниатюрная строка наверху) с денормализацией, нет огромного количества преимущества, которое будет иметься, просто объединив таблицы вместе. Тип денормализации, которая имеет тенденцию увеличивать производительность, IME, кэширует вычисленные значения вместо того, чтобы читать эти 10 000 строк, требуемых вычислить их.

11
ответ дан Mark Brackett 23 November 2019 в 00:33
поделиться

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

Для некоторых баз данных это не имеет значения, например, MS, SQL действительно знает надлежащий порядок соединения большую часть времени. Для некоторых (как IBM Informix) порядок имеет все значение.

3
ответ дан Ilya Kochetov 23 November 2019 в 00:33
поделиться

Разработка, что другие сказали,

Соединения, является просто декартовыми произведениями с некоторым блеском для губ. {1,2,3,4} X {1,2,3} дал бы нам 12 комбинаций (nXn=n^2). Этот вычисленный набор действует как ссылка, на которую применяются условия. DBMS применяет условия (как то, где оба левые и правые равняются 2 или 3) дать нам условие (условия) соответствия. На самом деле это более оптимизировано, но проблемой является то же. Изменения в размере наборов увеличили бы размер результата экспоненциально. Объем памяти и циклы CPU использовали, все произведены в экспоненциальных терминах.

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

-8
ответ дан questzen 23 November 2019 в 00:33
поделиться

Решение о денормализации или нормализации - довольно простой процесс, если учесть класс сложности соединения. Например, я склонен проектировать свои базы данных с нормализацией, когда запросы составляют O (k log n), где k относительно желаемой выходной величины.

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

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

Как правило, I ' ve всегда хранит нормализованную структуру и денормализованные кеши, которые можно реконструировать. В конце концов, эти кеши спасают мою задницу, чтобы решить будущие проблемы нормализации.

0
ответ дан 23 November 2019 в 00:33
поделиться
Другие вопросы по тегам:

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