Объединяются ли для ленивых людей?

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

Для него объединяются для ленивых людей, которые не заботятся о производительности. Это правда? Следует ли избегать использования объединений?

Ответ 1

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

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

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

Изменить: Есть редкие случаи, когда пользовательский код клиента может делать что-то более эффективно, чем простое соединение DB (см. комментарий meriton). Но это очень исключение.

Ответ 2

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

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

Вкратце: я не согласен. В СУБД, объединения фундаментальные. Если вы их не используете, вы не используете его как СУБД.

Ответ 3

Хорошо, он ошибается в общем случае.

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

Ответ 4

Нет, ты не должен.

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

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

Ответ 5

Если "ленивый" определяется как человек, который хочет писать меньше кода, я согласен. Если "ленивый" определяется как люди, которые хотят, чтобы инструменты делали то, что они умеют делать, я согласен. Поэтому, если он просто соглашается с Ларри Уолл (относительно атрибутов хороших программистов), я согласен с ним.

Ответ 6

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

Как сделать несколько вызовов в базе данных более эффективными, чем один вызов? Плюс SQL-движки оптимизированы при выполнении такого рода вещей.

Возможно, ваш коллега слишком ленив, чтобы изучить SQL.

Ответ 7

Да, вы должны.

И вы должны использовать С++ вместо С# из-за производительности. С# для ленивых людей.

Нет, нет, нет. Из-за производительности вы должны использовать C вместо С++. С++ для ленивых людей.

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

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

Ответ 8

"Это технически верно" - аналогично, база данных SQL бесполезна: какой смысл использовать ее, когда вы можете получить тот же результат, используя кучу CSV файлов и сопоставляя их с кодом? Черт возьми, любая абстракция для ленивых людей, вернемся к программированию в машинный код прямо на аппаратном уровне!;)

Кроме того, его утверждение неверно во всех, кроме самых запутанных случаях: РСУБД сильно оптимизированы для быстрого запуска JOIN. Реляционные системы управления базами данных, правильно?

Ответ 9

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

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

Обратите внимание, что я не усердно стараюсь избегать SQL-соединений.

Ответ 10

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

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

Ответ 11

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

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

Я оставляю это вам решать.

Ответ 12

Рассмотрим пример: таблицу со счетами-фактурами и связанную таблицу со списками позиций счета-фактуры. Рассмотрим псевдокод клиента:

for each (invoice in invoices)
    let invoiceLines = FindLinesFor(invoice)
...

Если у вас есть 100 000 счетов-фактур с 10 строками каждый, этот код будет искать 10 строк счетов из таблицы в 1 миллион, и он будет делать это 100 000 раз. По мере увеличения размера таблицы увеличивается количество операций выбора, и увеличивается стоимость каждой операции выбора.

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

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

Представьте себе, что вы сами это делаете. У вас есть алфавитный список студентов и блокнот со всеми отчетами о классе учащихся (по одной странице на класс). Блокнот сортируется по порядку по именам учеников в том же порядке, что и список. Как вы предпочитаете действовать?

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

Или:

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

Ответ 13

Звучит как классический случай ", я могу лучше писать". Другими словами, он видит что-то, что он видит в виде боли в шее (написав кучу объединений в SQL) и говоря: "Я уверен, что смогу написать это лучше и получить лучшую производительность". Вы должны спросить его, есть ли он умнее и б) более образован, чем типичный человек, который колен в коде Oracle или SQL Server. Шансы - это не так.

Ответ 14

Он, безусловно, ошибается. Хотя есть определенные плюсы для манипулирования данными в таких языках, как С# или Java, соединения в самой базе быстрее всего связаны с природой самого SQL.

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

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

Ответ 15

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

Ответ 16

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

Ответ 17

Нет, не только улучшены оптимизированы соединения в коде базы данных, которые используются в Ad-hoc С#/Java; но обычно можно применять несколько методов фильтрации, что дает еще лучшую производительность.

Ответ 18

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

select t1.field1 
from table1 t1
join table2 t2 
    on t1.id = t2.id
where t1.field2 = 'test'

Предположим, что у вас 10 миллионов записей в таблице1 и 1 миллион записей в таблице2. Предположим, что 9 миллионов записей в таблице 1 соответствуют предложению where. Предположим, что только 15 из них также находятся в таблице 2. Вы можете запустить эту инструкцию sql, которая, если правильно проиндексирована, займет миллисекунды и вернет 15 записей по сети только с одним столбцом данных. Или вы можете отправить десять миллионов записей с двумя столбцами данных и отдельно отправить еще 1 миллион записей с одним столбцом данных по сети и объединить их на веб-сервере.

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

Ответ 19

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

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

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

Итак, ответ определенно: Нет, JOINS не бесполезны вообще!

Ответ 20

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

Ответ 21

Если я серьезно не понял, логика в вопросе очень ошибочна

Если в B имеется 20 строк в B, 1000 строк в подразумевают 20k строк в B. В B не может быть всего 100 строк, если не существует много-много таблиц "AB" с 20k строками с содержащим отображение.

Итак, чтобы получить всю информацию о том, какая из 20 строк 100 B соответствует каждой строке A, вы также используете таблицу AB. Таким образом, это будет либо:

  • 3 набора результатов из 100, 1000 и 20 тыс. строк и клиент JOIN
  • один набор JOINed A-AB-B с 20k строками

Таким образом, "JOIN" в клиенте добавляет любое значение при анализе данных. Не то чтобы это неплохая идея. Если бы я извлекал один объект из базы данных, чем, возможно, имеет смысл разбить его на отдельные наборы результатов. Для вызова типа отчета я бы почти полностью разделил его на один.

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

Вы должны ПРИСОЕДИНИТЬСЯ где-нибудь, и то, что RDBMS хорошо. Я не хотел бы работать с любой обезьяной-клиентом кода, которая думает, что может сделать лучше.

Запоздалая мысль:

Для подключения к клиенту требуются постоянные объекты, такие как DataTables (в .net). Если у вас есть один сплющенный набор результатов, он может потребляться через что-то более легкое, как DataReader. Большой объем = много клиентских ресурсов, используемых для избежания создания базы данных JOIN.