Насколько дорого стоит JOINs в SQL? И/или, какой компромисс между исполнением и нормализацией?

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

Я знаю, что есть компромисс между нормализацией и производительностью, и мне интересно, что лучше всего подходит для рисования этой линии? В моей конкретной ситуации у меня есть система обмена сообщениями, в которой есть три различные таблицы: messages_threads (основной владелец сообщения), messages_recipients (кто участвует) и messages_messages (фактические сообщения + отметки времени).

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

Мой вопрос: насколько дорого стоит JOINS в SQL? Я мог бы, например, сохранить имя отправителя (которое я должен покинуть присоединиться к пользователям для извлечения) под полем в таблице messages_threads с именем "sendername" - но с точки зрения нормализации меня всегда учили избегать избыточности данных?

Где вы рисуете линию? Или я переоцениваю, как сбой производительности SQL-соединений?

Ответ 1

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

Производительность - это лишь одна из проблем, с которыми вам приходится иметь дело с базами данных. Путем дублирования данных вы рискуете предоставить несогласованные данные в своей базе данных, тем самым аннулируя один из основных принципов реляционных баз данных, согласованность (C in ACID) a.

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

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


a) Реверсирование производительности обычно можно сделать безопасным, используя триггеры для поддержания согласованности. Это, конечно, замедлит ваши обновления, но может по-прежнему позволять вашим выборам работать быстрее.

Ответ 2

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

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

Если вам действительно интересно, вы можете настроить бенчмарк. PHPMyAdmin сообщает, сколько времени потребовалось выполнить запрос; вы можете проверить время с окончательным соединением и без него. (Просто имейте в виду, что все запросы выбора phpmyadmin ограничены, поэтому вы можете ожидать более длительное время выполнения, если вы выбираете более 20 строк).

Ответ 3

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

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

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

Ответ 4

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

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

Ответ 5

Соединения - это стратегия повышения эффективности запроса. И вопреки другому ответу внешние соединения столь же эффективны, как и внутренние соединения в каждом продукте, который у меня есть возможность для текста, включая MySQL (оба основных механизма), SQL Server, Sybase и Oracle.

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

Ответ 6

ВСЕГДА ВСЕГДА предпочитают нормализацию. Мне ужасно, что денормализация STILL получает такое внимание.

NORMALIZE - это то, что настроены для двигателей баз данных.

Ответ 7

Невозможно или полезно ответить на вопрос о том, как дорогостоящие соединения.

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

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