Соединения SQL против одной таблицы: разница в производительности? - PullRequest
25 голосов
/ 25 января 2009

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

Ответы [ 7 ]

20 голосов
/ 25 января 2009

Держите базу данных в норме, пока вы не обнаружили узкое место. Тогда только после тщательного профилирования следует денормализовать.

В большинстве случаев наличие хорошего набора индексов и обновленной статистики решит большинство проблем производительности и блокировки без какой-либо денормализации.

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

16 голосов
/ 25 января 2009

Майкл Джексон (не , что один) , как известно, сказал, что ,

  • Первое правило оптимизации программы: не делайте этого.
  • Второе правило оптимизации программы - только для экспертов: пока не делайте этого.

Это было, вероятно, до появления СУБД, но я думаю, что он расширил бы Правила, чтобы включить их.

Выбор нескольких таблиц почти всегда необходим для нормализованной модели данных; как это часто бывает с такого рода вопросом, «правильный» ответ на «денормализацию?» Вопрос зависит от нескольких факторов.

Платформа СУБД.

Относительная производительность запросов к нескольким таблицам зависит от платформы, на которой работает ваше приложение: уровень сложности оптимизаторов запросов может варьироваться. Например, MySQL, по моему опыту, очень быстро работает с запросами из одной таблицы, но не очень хорошо оптимизирует запросы с несколькими объединениями. Это не настоящая проблема с меньшими таблицами (скажем, менее 10 000 строк), но на самом деле больно с большими (более 10 миллионов) таблицами.

Объем данных

Если вы не смотрите на таблицы в области строк размером более 100K, проблем быть не должно. Если вы посмотрите на размеры таблиц в сотнях строк, я бы даже не стал задумываться об индексации.

(Де-) нормализация

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

Требования / Ограничения

Каким требованиям к производительности вы пытаетесь соответствовать? У вас есть фиксированное оборудование или бюджет? Иногда повышение производительности может быть наиболее легко - и даже самым дешевым - достигнуто с помощью обновления оборудования. Какие объемы транзакций вы ожидаете? Система бухгалтерского учета для малого бизнеса имеет совершенно иной профиль, например, для Twitter.

Одна последняя мысль поражает меня: если вы достаточно денормализуете, чем ваша база данных отличается от плоского файла? SQL превосходен для гибких данных и многомерного переноса, но он может быть на порядок (как минимум) медленнее, чем прямой последовательный или довольно просто проиндексированный файл.

4 голосов
/ 24 марта 2009

Разница в производительности?

Разница в здравомыслии.

2 голосов
/ 25 января 2009

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

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

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

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

2 голосов
/ 25 января 2009

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

Большинство современных РСУБД довольно хороши в этом отношении.

Прежде чем вы думаете, что денормализация в некоторых случаях является «хорошей», подумайте над этим: обычно вас не интересует каждый атрибут. Поэтому загрузка ненужных данных с диска неэффективна (как правило, наименее эффективный компонент базы данных). Это может быть намного хуже, если у вас есть денормализованный дизайн, с множеством избыточных данных подряд. Еще хуже, если вам придется обновлять все эти избыточные данные. Гораздо эффективнее загрузить несколько узких таблиц, содержащих только интересующие столбцы, и объединить их. Опять же, это зависит от базы данных, поэтому без профилирования у вас нет никакой подсказки.

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

1 голос
/ 25 января 2009

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

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

0 голосов
/ 25 января 2009

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

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

...