"[MySQL] Объединяет зло" - Кэл Хендерсон

Flickr Cal Henderson дал основной доклад для DjangoCon 2008. Он кратко затронул использование Django в использовании табличных объединений в запросах, утверждая: "вы не используете объединения, когда попадаете в определенный масштаб". Я ожидаю, что Хендерсон знает это до мозга костей, но кто-нибудь знает, какова вероятная аргументация его претензии?

Ответы

Ответ 1

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

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

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

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

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

Ответ 2

Все большие масштабируемые системы должны обойтись без соединения. Причина в том, что для высокораспространенных баз данных, таких как BigTable, которые использует Google, данные настолько велики, что они выходят за пределы одной машины. Объединение двух таблиц размером в GB не может быть масштабируемо. На самом деле, если вы делаете много объединений, вы увидите около 5 миллионов строк, ваши РСУБД начнут звенеть, опираясь на индексы. Индексы индексов также намного сложнее распределенных баз данных и баз данных, таких как mongodb, couchdb и т.д.

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

Когда мы доберемся до Терабайтов данных, Join будет в прошлом.

Ответ 3

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

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

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

Ответ 4

Я склонен не соглашаться, потому что, если вы хорошо проектируете свою базу данных, вы можете получить производительность. У нас есть хранилище данных с несколькими терабайтами, смоделированное с помощью схемы звезд Кимбалла, и вы должны ПРИСОЕДИНИТЬ ФАКТЫ к измерениям, чтобы делать какой-либо анализ, и он выполняет (потому что он разбит на разделы и индексирован). Но я должен произвести 200 м строк итогового вывода в одном процессе. Такой объем информации просто не будет нажиматься на пользователя.

Однако для типичных клиентских веб-приложений, которые возвращают ограниченный объем данных с каждым поколением страниц, сколько вы присоединяетесь? Вместо этого сервер приложений может запрашивать строки, затем запрашивать связанные строки и т.д. Когда реляционная база данных не была доступна на 64K небольшой модели 8086, запрограммированной на C, у нас была библиотека ISAM, и нам приходилось искать и читать в одном таблицу, а затем искать и читать в другой таблице. Если вы не имеете дело с большим количеством данных, это так же легко сделать сами, как это.

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

Ответ 5

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

Ответ 6

Когда вы увеличиваете масштаб, вы начинаете выбрасывать возможности, потому что они что-то стоят. Подзапросы сначала; то в итоге даже присоединяется. Это позволит вам делать все, что вам нужно, с таблицами и индексами - например, Google.

Базы данных SQL, как правило, построены на isams - это ничего, кроме таблиц и индексов. Поэтому он просто сказал, что приближается к металлу. Что, подумайте об этом, я думаю, это MyISAM. Таким образом, вы избавляете оптимизатора от необходимости выяснять его. И я уверен, оттуда. Но первым шагом было бы ИМХО, чтобы пролить накладные расходы на SQL-парсер/оптимизатор и напрямую манипулировать таблицами и индексами. Как и раньше, в foxpro и т.д.

Ответ 7

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