В чем разница между ОБЪЕДИНЕНИЕМ и ОБЪЕДИНЕНИЕМ ВСЕХ?

#mysql #sql #select #insert #insert-select

#sql #объединение #объединение-все

Вопрос:

В чем разница между UNION и UNION ALL ?

Ответ №1:

UNION удаляет повторяющиеся записи (где все столбцы в результатах одинаковы), UNION ALL не делает.

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

Для выявления дубликатов записи должны быть сопоставимых типов, а также совместимых типов. Это будет зависеть от системы SQL. Например, система может обрезать все длинные текстовые поля, чтобы сделать короткие текстовые поля для сравнения (MS Jet), или может отказаться сравнивать двоичные поля (ORACLE)

Пример ОБЪЕДИНЕНИЯ:

 SELECT 'foo' AS bar UNION SELECT 'foo' AS bar
  

Результат:

  ----- 
| bar |
 ----- 
| foo |
 ----- 
1 row in set (0.00 sec)
  

Пример ОБЪЕДИНЕНИЯ ВСЕХ:

 SELECT 'foo' AS bar UNION ALL SELECT 'foo' AS bar
  

Результат:

  ----- 
| bar |
 ----- 
| foo |
| foo |
 ----- 
2 rows in set (0.00 sec)
  

Комментарии:

1. Следствием этого является то, что объединение намного менее эффективно, поскольку оно должно сканировать результат на наличие дубликатов

2. Просто заметил, что здесь много хороших комментариев / ответов, поэтому я включил флаг wiki и добавил примечание о производительности…

3. ОБЪЕДИНЕНИЕ ВСЕХ может быть медленнее, чем ОБЪЕДИНЕНИЕ в реальных случаях, когда сеть, такая как Интернет, является узким местом. Стоимость переноса множества повторяющихся строк может превышать выигрыш во времени выполнения запроса. Это должно анализироваться в каждом конкретном случае.

Ответ №2:

Оба UNION и UNION ALL объединяют результат двух разных SQLL. Они отличаются тем, как они обрабатывают дубликаты.

  • ОБЪЕДИНЕНИЕ выполняет РАЗЛИЧИЕ в результирующем наборе, устраняя любые повторяющиеся строки.

  • ОБЪЕДИНЕНИЕ ВСЕХ не удаляет дубликаты, и поэтому оно быстрее, чем ОБЪЕДИНЕНИЕ.

Примечание: при использовании этой команды все выбранные столбцы должны иметь один и тот же тип данных.

Пример: если у нас есть две таблицы: 1) Сотрудник и 2) Клиент

  1. Данные таблицы сотрудников:

введите описание изображения здесь

  1. Данные таблицы клиентов:

введите описание изображения здесь

  1. Пример ОБЪЕДИНЕНИЯ (удаляет все повторяющиеся записи):

введите описание изображения здесь

  1. Пример ОБЪЕДИНЕНИЯ ВСЕХ (он просто объединяет записи, а не устраняет дубликаты, поэтому он быстрее, чем ОБЪЕДИНЕНИЕ):

введите описание изображения здесь

Комментарии:

1. «все выбранные столбцы должны иметь один и тот же тип данных» — на самом деле все не так строго (что не очень хорошо с точки зрения реляционной модели!). Стандарт SQL гласит, что их соответствующий дескриптор столбца должен быть одинаковым, за исключением имени.

Ответ №3:

UNION удаляет дубликаты, тогда UNION ALL как нет.

Для удаления дубликатов результирующий набор должен быть отсортирован, и это может повлиять на производительность ОБЪЕДИНЕНИЯ в зависимости от объема сортируемых данных и настроек различных параметров СУБД (для Oracle PGA_AGGREGATE_TARGET с WORKAREA_SIZE_POLICY=AUTO or SORT_AREA_SIZE и SOR_AREA_RETAINED_SIZE if WORKAREA_SIZE_POLICY=MANUAL ).

В принципе, сортировка выполняется быстрее, если ее можно выполнить в памяти, но применяется то же самое предостережение относительно объема данных.

Конечно, если вам нужны данные, возвращаемые без дубликатов, вы должны использовать UNION, в зависимости от источника ваших данных.

Я бы прокомментировал первое сообщение, чтобы квалифицировать комментарий «гораздо менее эффективный», но для этого недостаточно репутации (баллов).

Комментарии:

1. «Чтобы удалить дубликаты, результирующий набор должен быть отсортирован» — возможно, вы имеете в виду конкретного поставщика, но в вопросе нет тегов, специфичных для конкретного поставщика. Даже если бы это было, не могли бы вы доказать, что дубликаты не могут быть удалены без сортировки?

2. distinct будет «неявно» сортировать результаты, потому что удаление дубликатов происходит быстрее в отсортированном наборе. это не означает, что возвращаемый результирующий набор фактически отсортирован таким образом, но в большинстве случаев distinct (и, следовательно, UNION) будут внутренне сортировать набор результатов.

Ответ №4:

В ORACLE: UNION не поддерживает типы столбцов BLOB (или CLOB), UNION ALL поддерживает.

Комментарии:

1. То же самое относится и к MS SQL с несопоставимыми типами столбцов, такими как XML

Ответ №5:

Основное различие между ОБЪЕДИНЕНИЕМ и ОБЪЕДИНЕНИЕМ ВСЕХ заключается в том, что операция объединения удаляет дублированные строки из результирующего набора, но объединение всех возвращает все строки после объединения.

из http://zengin.wordpress.com/2007/07/31/union-vs-union-all /

Комментарии:

1. К сожалению, связанный wordpress.com статья, похоже, больше не доступна. Упс! Эта страница не может быть найдена У тебя случайно нет альтернативного URL, Джордж?

Ответ №6:

ОБЪЕДИНЕНИЕ
UNION Команда используется для выбора связанной информации из двух таблиц, во многом аналогично JOIN команде. Однако при использовании UNION команды все выбранные столбцы должны иметь один и тот же тип данных. С UNION помощью выбираются только отдельные значения.

ОБЪЕДИНЕНИЕ ВСЕХ
UNION ALL Команда равна UNION команде, за исключением того, что UNION ALL выбирает все значения.

Разница между Union и Union all заключается в том, что Union all не устраняет повторяющиеся строки, вместо этого он просто извлекает все строки из всех таблиц, соответствующих специфике вашего запроса, и объединяет их в таблицу.

UNION Оператор эффективно выполняет a SELECT DISTINCT для набора результатов. Если вы знаете, что все возвращаемые записи уникальны из вашего объединения, используйте UNION ALL вместо этого, это дает более быстрые результаты.

Ответ №7:

Вы можете избежать дубликатов и по-прежнему работать намного быстрее, чем UNION DISTINCT (который на самом деле такой же, как UNION), выполнив запрос следующим образом:

SELECT * FROM mytable WHERE a=X UNION ALL SELECT * FROM mytable WHERE b=Y AND a!=X

Обратите внимание на AND a!=X часть. Это намного быстрее, чем ОБЪЕДИНЕНИЕ.

Комментарии:

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

2. @FrankSchmitt — спасибо за этот ответ; этот бит о подзапросах — это именно то, что я хотел знать!

Ответ №8:

Просто чтобы добавить свои два цента к обсуждению здесь: можно понимать UNION оператор как чистое ОБЪЕДИНЕНИЕ, ориентированное на МНОЖЕСТВО — например, set A= {2,4,6,8}, set B = {1,2,3,4}, ОБЪЕДИНЕНИЕ B = {1,2,3,4,6,8}

При работе с наборами вы бы не хотели, чтобы числа 2 и 4 появлялись дважды, поскольку элемент либо есть, либо его нет в наборе.

Однако в мире SQL вы можете захотеть видеть все элементы из двух наборов вместе в одном «пакете» {2,4,6,8,1,2,3,4} . И для этой цели T-SQL предлагает оператор UNION ALL .

Комментарии:

1. Придирка: UNION ALL не «предлагается» T-SQL. UNION ALL является частью стандарта ANSI SQL и не относится к MS SQL Server.

2. Комментарий ‘Nitpick’ может означать, что вы не можете использовать «Union All» в TSQL, но вы можете. Конечно, в комментарии этого не сказано , но кто-то, читающий его, может сделать вывод.

3. Кстати, мне очень нравится обсуждение этого ответа, ориентированное на математику!

Ответ №9:

ОБЪЕДИНЕНИЕ — приводит к отдельным записям

в то время как

ОБЪЕДИНЕНИЕ ВСЕХ — приводит ко всем записям, включая дубликаты.

Оба являются блокирующими операторами, и поэтому я лично предпочитаю использовать ОБЪЕДИНЕНИЯ вместо блокирующих операторов (ОБЪЕДИНЕНИЕ, ПЕРЕСЕЧЕНИЕ, ОБЪЕДИНЕНИЕ ВСЕХ и т. Д.) В любое время.

Чтобы проиллюстрировать, почему операция объединения работает плохо по сравнению с объединением всех, проверьте следующий пример.

 CREATE TABLE #T1 (data VARCHAR(10))

INSERT INTO #T1
SELECT 'abc'
UNION ALL
SELECT 'bcd'
UNION ALL
SELECT 'cde'
UNION ALL
SELECT 'def'
UNION ALL
SELECT 'efg'


CREATE TABLE #T2 (data VARCHAR(10))

INSERT INTO #T2
SELECT 'abc'
UNION ALL
SELECT 'cde'
UNION ALL
SELECT 'efg'
  

введите описание изображения здесь

Ниже приведены результаты операций ОБЪЕДИНЕНИЯ ВСЕХ и ОБЪЕДИНЕНИЯ.

введите описание изображения здесь

Оператор ОБЪЕДИНЕНИЯ эффективно выполняет SELECT DISTINCT в наборе результатов. Если вы знаете, что все возвращаемые записи уникальны для вашего union, используйте вместо UNION ALL , это дает более быстрые результаты.

Использование ОБЪЕДИНЕНИЯ приводит к различным операциям сортировки в плане выполнения. Доказательство, подтверждающее это утверждение, показано ниже:

введите описание изображения здесь

Комментарии:

1. Все, что уже было сказано в этом ответе, слишком запутанно, чтобы быть полезным (предлагая объединения вместо объединений, когда они выполняют разные действия, указывая «блокировку» в качестве причины, не объясняя, что вы подразумеваете под этим или к каким серверам баз данных это относится), или сильно вводит в заблуждение (ваши проценты на вашем скриншоте указаныне применимо к реальному фактическому использованию UNION / UNION ALL ).

2. Блокирующие операторы — хорошо известные операторы в TSQL. Все, что делают блокирующие операторы, может быть достигнуто путем объединения, но не наоборот. Отдельная операция сортировки обведена на рисунке, чтобы показать, почему объединение всех работает лучше, чем объединение, а также показать, где именно она существует в плане выполнения. Не стесняйтесь добавлять больше данных в таблицы T1 и T2, чтобы поиграть с процентами!

3. Технически вы МОЖЕТЕ получить результаты a union , используя комбинацию join s и некоторые действительно неприятные case s, но это делает запрос практически невозможным для чтения и обслуживания, и, по моему опыту, это также ужасно для производительности. Сравнить: select foo.bar from foo union select fizz.buzz from fizz с select case when foo.bar is null then fizz.buzz else foo.bar end from foo join fizz where foo.bar is null or fizz.buzz is null

4. @DBA Ваш ответ актуален только для пользователей MS SQL Server. OP никогда не упоминал RDBMS, которые они используют — они могут использовать MySQL, PostgreSQL, Oracle, SQLite, …

Ответ №10:

Не уверен, что имеет значение, какая база данных

UNION и UNION ALL должен работать на всех серверах SQL.

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

Комментарии:

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

2. @onedayкогда я предполагал, что OP использовал фразу «SQL Servers» как синоним для всех СУБД (например, MySQL, PostgreSQL, Oracle, SQL Server). Однако формулировка неудачна (и, конечно, я могу ошибаться).

3. @FrankSchmitt: ни один из перечисленных вами продуктов не является настоящей СУБД 🙂

4. @onedayкогда хотите уточнить? По крайней мере en.wikipedia.org/wiki/Relational_database_management_system кажется, он согласен со мной — в нем явно упоминаются Microsoft SQL Server, Oracle Database и MySQL. Или вы придираетесь к разнице между Oracle и Oracle Database, например?

5. @FrankSchmitt, для меня это похоже на Windows, а не на дыры в стенах домов, а не на операционную систему M $. «Основанный на мнениях», конечно 🙂

Ответ №11:

(Из онлайн-книги Microsoft SQL Server)

ОБЪЕДИНЕНИЕ [ВСЕ]

Указывает, что несколько наборов результатов должны быть объединены и возвращены как один набор результатов.

ВСЕ

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

UNION это займет слишком много времени, так как к результатам применяется поиск повторяющихся строк like DISTINCT .

 SELECT * FROM Table1
UNION
SELECT * FROM Table2
  

эквивалентно:

 SELECT DISTINCT * FROM (
    SELECT * FROM Table1
    UNION ALL
    SELECT * FROM Table2) DT
  

Побочным эффектом применения DISTINCT к результатам является операция сортировки результатов.

UNION ALL результаты будут показаны в произвольном порядке по результатам, но UNION результаты будут показаны как ORDER BY 1, 2, 3, ..., n (n = column number of Tables) примененные к результатам. Вы можете увидеть этот побочный эффект, когда у вас нет повторяющейся строки.

Ответ №12:

Я добавляю пример,

ОБЪЕДИНЕНИЕ, оно сливается с distinct —> медленнее, потому что его нужно сравнивать (в Oracle SQL developer выберите query, нажмите F10, чтобы просмотреть анализ затрат).

ОБЪЕДИНЕНИЕ ВСЕХ, это слияние без distinct —> быстрее.

 SELECT to_date(sysdate, 'yyyy-mm-dd') FROM dual
UNION
SELECT to_date(sysdate, 'yyyy-mm-dd') FROM dual;
  

и

 SELECT to_date(sysdate, 'yyyy-mm-dd') FROM dual
UNION ALL
SELECT to_date(sysdate, 'yyyy-mm-dd') FROM dual;
  

Ответ №13:

UNION объединяет содержимое двух структурно совместимых таблиц в одну объединенную таблицу.

  • Разница:

Разница между UNION и UNION ALL заключается в том, что UNION will опускаются повторяющиеся записи, тогда UNION ALL как будут содержать повторяющиеся записи.

Union Набор результатов сортируется в порядке возрастания, тогда UNION ALL как набор результатов не сортируется

UNION выполняет a DISTINCT для своего результирующего набора, чтобы исключить любые повторяющиеся строки. Тогда UNION ALL как не будет удалять дубликаты и, следовательно, быстрее, чем UNION .*

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

Комментарии:

1. «Набор результатов объединения сортируется в порядке возрастания» — если нет ORDER BY , отсортированные результаты не гарантируются. Может быть, вы имеете в виду конкретного поставщика SQL (даже тогда, в порядке возрастания, что именно …?), Но в этом вопросе нет тегов, специфичных для поставщика.

2. «объединяет содержимое двух структурно совместимых таблиц» — я думаю, вы очень хорошо изложили эту часть 🙂

Ответ №14:

Предположим, что у вас есть две таблицы Teacher amp; Student

У обоих есть 4 столбца с разными именами, например

 Teacher - ID(int), Name(varchar(50)), Address(varchar(50)), PositionID(varchar(50))
  

введите описание изображения здесь

 Student- ID(int), Name(varchar(50)), Email(varchar(50)), PositionID(int)
  

введите описание изображения здесь

Вы можете применить ОБЪЕДИНЕНИЕ или ОБЪЕДИНЕНИЕ ВСЕХ для тех двух таблиц, которые имеют одинаковое количество столбцов. Но у них разные имена или типы данных.

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

 SELECT * FROM Student
UNION
SELECT * FROM Teacher
  

результатом будет

введите описание изображения здесь

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

 SELECT * FROM Student
UNION ALL
SELECT * FROM Teacher
  

Вывод
введите описание изображения здесь

Производительность:

Очевидно, что производительность UNION ALL лучше, чем UNION, поскольку они выполняют дополнительную задачу по удалению повторяющихся значений. Вы можете проверить это по расчетному времени выполнения, нажав ctrl L в MSSQL

Комментарии:

1. Действительно? Для результата в четыре строки ?! Я бы подумал, что это сценарий, в котором вы хотели бы использовать UNION для передачи намерения (т. Е. Без дубликатов), потому UNION ALL что Вряд ли это даст какой-либо реальный прирост производительности в абсолютном выражении.

Ответ №15:

ОБЪЕДИНЕНИЕ удаляет повторяющиеся записи, а ОБЪЕДИНЕНИЕ ВСЕХ — нет. Но нужно проверить большую часть данных, которые будут обрабатываться, и столбец и тип данных должны быть одинаковыми.

поскольку union внутренне использует «отдельное» поведение для выбора строк, следовательно, это более затратно с точки зрения времени и производительности. Нравится

 select project_id from t_project
union
select project_id from t_project_contact  
  

это дает мне 2020 записей

с другой стороны

 select project_id from t_project
union all
select project_id from t_project_contact
  

дает мне более 17402 строк

с точки зрения приоритета оба имеют одинаковый приоритет.

Ответ №16:

Если нет ORDER BY , a UNION ALL может возвращать строки по ходу выполнения, тогда как a UNION заставит вас ждать до самого конца запроса, прежде чем выдавать вам весь результирующий набор сразу. Это может иметь значение в ситуации тайм-аута — a UNION ALL как бы поддерживает соединение.

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

Комментарии:

1. Но ваш первый фрагмент результатов может быть одной строкой, дублируемой много раз: насколько это полезно ?!

Ответ №17:

Еще одна вещь, которую я хотел бы добавить-

Объединение: — Результирующий набор сортируется в порядке возрастания.

Объединение всех: — Результирующий набор не отсортирован. просто добавляется вывод двух запросов.

Комментарии:

1. Верно ! ОБЪЕДИНЕНИЕ может изменить порядок двух подрезультатов.

2. Это неправильно. A UNION НЕ будет сортировать результат в порядке возрастания. Любой порядок, который вы видите в результате без использования order by , является чистым совпадением. СУБД может свободно использовать любую стратегию, которая, по ее мнению, эффективна для удаления дубликатов. Это может быть сортировка, но это также может быть алгоритм хеширования или что-то совершенно другое — и стратегия будет меняться с количеством строк. Объект union , который отображается отсортированным по 100 строкам, может содержать не 100 000 строк

3. Без предложения ORDER BY в запросе СУБД может возвращать строки в любой последовательности. Наблюдение, что результирующий набор из операции ОБЪЕДИНЕНИЯ возвращается «в порядке возрастания», является лишь побочным продуктом операции «сортировки по уникальности», выполняемой базой данных. Наблюдаемое поведение не гарантируется. Так что не полагайтесь на это. Если спецификация должна возвращать строки в определенном порядке, добавьте соответствующее ORDER BY предложение.

Ответ №18:

Важно! Разница между Oracle и Mysql: Предположим, что t1 t2 не имеют повторяющихся строк между ними, но у них есть отдельные повторяющиеся строки. Пример: у t1 продажи с 2017 года, а у t2 с 2018 года

 SELECT T1.YEAR, T1.PRODUCT FROM T1

UNION ALL

SELECT T2.YEAR, T2.PRODUCT FROM T2
  

В ORACLE UNION ALL извлекает все строки из обеих таблиц. То же самое произойдет и в MySQL.

Однако:

 SELECT T1.YEAR, T1.PRODUCT FROM T1

UNION

SELECT T2.YEAR, T2.PRODUCT FROM T2
  

В ORACLE UNION извлекает все строки из обеих таблиц, потому что между t1 и t2 нет повторяющихся значений. С другой стороны, в MySQL результирующий набор будет содержать меньше строк, потому что в таблице t1, а также в таблице t2 будут повторяющиеся строки!

Комментарии:

1. Это неправильно. x union y есть select distinct * from (x union all y) . select 1 from dual union select 1 from dual amp; (select 1 from dual union all select 1 from dual) union select 1 from dual оба возвращают 1 строку. PS Я не знаю, подразумеваете ли вы под t1 amp; t2 T1 amp; T1, но важно то, что находится в selects . PS Для примера UNION (distinct) вы четко не говорите, с точки зрения дубликатов, что вводится и для каждой СУБД, что она возвращает или почему. Используйте достаточно слов, предложений и ссылок на части примеров, чтобы было понятно.

Ответ №19:

UNION ALL также работает и с другими типами данных. Например, при попытке объединить пространственные типы данных. Например:

 select a.SHAPE from tableA a
union
select b.SHAPE from tableB b
  

приведет к

The data type geometry cannot be used as an operand to the UNION, INTERSECT or EXCEPT operators because it is not comparable.

Однако union all не будет.