Union ms sql: UNION (Transact-SQL) — SQL Server

Содержание

Использование Union вместо OR / Хабр

puyol_dev2

Время на прочтение
3 мин

Количество просмотров

8.4K

SQL *Microsoft SQL Server *

Recovery mode

Перевод

Автор оригинала:

Derek Dieter

Иногда медленные запросы можно исправить, немного изменив запрос. Один из таких примеров может быть проиллюстрирован, когда несколько значений сравниваются в предложении WHERE с помощью оператора OR или IN. Часто OR может вызывать сканирование индекса или таблицы, которая может не быть предпочтительным планом выполнения с точки зрения потребления ввода-вывода или общей скорости запросов.

Многие переменные вступают в игру, когда оптимизатор запросов создает план выполнения. Эти переменные включают в себя множество характеристик оборудования, настроек экземпляра, настроек базы данных, статистики (таблица, индекс, auto-generated), а также способ написания запроса. Здесь мы меняем способ написания запроса. Каким бы неожиданным это ни казалось, даже если два разных запроса могут возвращать одни и те же результаты, путь, по которому они идут, может быть совершенно разным в зависимости от формата запроса.

UNION vs OR


В большей части моего опыта работы с SQL Server, OR обычно менее эффективен, чем UNION. То, что обычно происходит с OR, это то, что он чаще вызывает сканирование. Это порой может быть лучший путь для некоторых случаев, и я оставлю это отдельной статье, но в целом я обнаружил, что когда затрагивается большое количество записей — это является основной причиной медлительности. Итак, давайте начнем наше сравнение.

Вот наш оператор OR:

SELECT SalesOrderID, *
FROM sales.SalesOrderDetail
WHERE ProductID = 750 OR ProductID = 953

Из этого плана выполнения мы видим, что мы выполняем сканирование 121 000 строк. (Вы не можете видеть количество строк, но это так).

Теперь выполним тот же запрос, но написанный с использованием UNION вместо OR:

SELECT [SalesOrderID], *
FROM sales.SalesOrderDetail
WHERE ProductID = 750
UNION
SELECT [SalesOrderID], *
FROM sales.SalesOrderDetail
WHERE ProductID = 953

Здесь мы видим две ветви операций. Одна ветвь затрагивает 358 строк, а другая — 346 строк. Обе ветви встречаются для выполнения операции конкатенации, объединяющей оба набора результатов. У нас есть два отдельных поиска, но у нас также есть поиск ключей для получения необходимого списка SELECT. Это не было необходимо для операции сканирования, потому что мы все равно затрагивали все строки в операции сканирования, таким образом, данные были получены во время сканирования, а не после. Это связано с индексом и нужными нам строками, а не с UNION или OR. Однако я скажу, что выборка (select) также является фактором выбора поиска против сканирования (seek vs scan), но мы проигнорируем это в этой статье.

Объяснение


Почему UNION вызывает больше поисков вместо сканирований, потому что каждая операция должна удовлетворять определенному требованию селективности, чтобы претендовать на поиск. (Селективность — это уникальность конкретного фильтруемого столбца). OR происходит в одной операции, так что, когда селективность для каждого столбца объединяется и она превышает определенный процент, то сканирование считается более эффективным.

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

Следует также отметить, что предложение OR работает так же, как оператор IN.

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

Теги:

  • sql
  • sql server
  • query planning

Хабы:

  • SQL
  • Microsoft SQL Server

SQL — класс UNION

Оператор/класс UNION используется для объединения результатов двух или более SELECT без возврата каких-либо повторяющихся строк.

Для того, чтобы использовать оператор UNION, каждый оператор SELECT, должен иметь

  • Одинаковое количество выбранных столбцов
  • Одинаковое количество выбранных столбцов выражений
  • Тот же тип данных
  • Иметь их в том же порядке

Но они не должны быть одинаковой длины.

Синтаксис

Основной синтаксис оператора UNION следующий:

SELECT column1 [, column2 ]
FROM table1 [, table2 ]
[WHERE condition]
UNION
SELECT column1 [, column2 ]
FROM table1 [, table2 ]
[WHERE condition]

 

Здесь, данное условие может быть любое данное выражение основано на вашем требовании.

Пример

Рассмотрим следующие две таблицы.

Таблица 1 — Таблица CUSTOMERS выглядит следующим образом.

+----+----------+-----+-----------+----------+
| ID | NAME     | AGE | ADDRESS   | SALARY   |
+----+----------+-----+-----------+----------+
|  1 | Maxim    |  35 | Moscow    | 21000.00 |
|  2 | AndreyEx |  38 | Krasnodar | 55500. 00 |
|  3 | Oleg     |  33 | Rostov    | 34000.00 |
|  4 | Masha    |  35 | Moscow    | 34000.00 |
|  5 | Ruslan   |  34 | Omsk      | 45000.00 |
|  6 | Dima     |  32 | SP        | 45000.00 |
|  7 | Roma     |  34 | SP        | 10000.00 |
+----+----------+-----+-----------+----------+

 

 

Таблица 2 — Таблица ORDERS выглядит следующим образом:

+-----+---------------------+-------------+--------+
|OID  | DATE                | CUSTOMER_ID | AMOUNT |
+-----+---------------------+-------------+--------+
| 102 | 2017-01-08 00:00:00 |           3 |  34200 |
| 100 | 2017-01-08 00:00:00 |           3 |  25000 |
| 101 | 2017-02-10 00:00:00 |           2 |  23450 |
| 103 | 2017-03-12 00:00:00 |           4 |  34000 |
+-----+---------------------+-------------+--------+

 

Теперь, давайте объединим эти две таблицы в нашем операторе SELECT следующим образом:

SQL> SELECT  ID, NAME, AMOUNT, DATE
   FROM CUSTOMERS
   LEFT JOIN ORDERS
   ON CUSTOMERS. ID = ORDERS.CUSTOMER_ID
UNION
   SELECT  ID, NAME, AMOUNT, DATE
   FROM CUSTOMERS
   RIGHT JOIN ORDERS
   ON CUSTOMERS.ID = ORDERS.CUSTOMER_ID;

 

Это произведет следующий результат:

+------+----------+--------+---------------------+
| ID   | NAME     | AMOUNT | DATE                |
+------+----------+--------+---------------------+
|    1 | Maxim    |   NULL | NULL                |
|    2 | AndreyEx |  23450 | 2017-02-10 00:00:00 |
|    3 | Oleg     |  34200 | 2017-01-08 00:00:00 |
|    3 | Oleg     |  25000 | 2017-01-08 00:00:00 |
|    4 | Masha    |  34000 | 2017-03-12 00:00:00 |
|    5 | Ruslan   |   NULL | NULL                |
|    6 | Dima     |   NULL | NULL                |
|    7 | Roma     |   NULL | NULL                |
+------+----------+--------+---------------------+

Класс UNION ALL

Оператор UNION ALL используется для объединения результатов двух SELECT включая повторяющиеся строки.

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

Синтаксис

Основной синтаксис UNION ALL следующий:

SELECT column1 [, column2 ]
FROM table1 [, table2 ]
[WHERE condition]
UNION ALL
SELECT column1 [, column2 ]
FROM table1 [, table2 ]
[WHERE condition]

 

Вот, данное состояние может быть любое выражение, основанное на вашем требовании.

Пример

Рассмотрим следующие две таблицы,

Таблица 1 — Таблица CUSTOMERS выглядит следующим образом:

+----+----------+-----+-----------+----------+
| ID | NAME     | AGE | ADDRESS   | SALARY   |
+----+----------+-----+-----------+----------+
|  1 | Maxim    |  35 | Moscow    | 21000.00 |
|  2 | AndreyEx |  38 | Krasnodar | 55500.00 |
|  3 | Oleg     |  33 | Rostov    | 34000.00 |
|  4 | Masha    |  35 | Moscow    | 34000.00 |
|  5 | Ruslan   |  34 | Omsk      | 45000.00 |
|  6 | Dima     |  32 | SP        | 45000.00 |
|  7 | Roma     |  34 | SP        | 10000.00 |
+----+----------+-----+-----------+----------+

 

Таблица 2 — таблица ORDERS следующая:

+-----+---------------------+-------------+--------+
|OID  | DATE                | CUSTOMER_ID | AMOUNT |
+-----+---------------------+-------------+--------+
| 102 | 2017-01-08 00:00:00 |           3 |  34200 |
| 100 | 2017-01-08 00:00:00 |           3 |  25000 |
| 101 | 2017-02-10 00:00:00 |           2 |  23450 |
| 103 | 2017-03-12 00:00:00 |           4 |  34000 |
+-----+---------------------+-------------+--------+

 

Теперь, давайте объединим эти две таблиц в нашем операторе SELECT следующим образом:

SQL> SELECT  ID, NAME, AMOUNT, DATE
   FROM CUSTOMERS
   LEFT JOIN ORDERS
   ON CUSTOMERS. ID = ORDERS.CUSTOMER_ID
UNION ALL
   SELECT  ID, NAME, AMOUNT, DATE
   FROM CUSTOMERS
   RIGHT JOIN ORDERS
   ON CUSTOMERS.ID = ORDERS.CUSTOMER_ID;

 

Это произведет следующий результат:

+------+----------+--------+---------------------+
| ID   | NAME     | AMOUNT | DATE                |
+------+----------+--------+---------------------+
|    1 | Maxim    |   NULL | NULL                |
|    2 | AndreyEx |  23450 | 2017-02-10 00:00:00 |
|    3 | Oleg     |  34200 | 2017-01-08 00:00:00 |
|    3 | Oleg     |  25000 | 2017-01-08 00:00:00 |
|    4 | Masha    |  34000 | 2017-03-12 00:00:00 |
|    5 | Ruslan   |   NULL | NULL                |
|    6 | Dima     |   NULL | NULL                |
|    7 | Roma     |   NULL | NULL                |
|    3 | Oleg     |  34200 | 2017-01-08 00:00:00 |
|    3 | Oleg     |  25000 | 2017-01-08 00:00:00 |
|    2 | AndreyEx |  23450 | 2017-02-10 00:00:00 |
|    4 | Masha    |  34000 | 2017-03-12 00:00:00 |
+------+----------+--------+---------------------+

 

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

  • Класс INTERSECT— используется в SQL для объединения два SELECT, но возвращает строки только с первым SELECT, которые идентичны со строками во втором SELECT.
  • Класс EXCEPT — объединяет два SELECT и возвращает строку из первого SELECT, не возвращенных вторым SELECT.

Если вы нашли ошибку, пожалуйста, выделите фрагмент текста и нажмите Ctrl+Enter.

Как эффективно использовать UNION в SQL Server | Джейми Бернс | Изучение SQL

Как эффективно использовать UNION в SQL Server | Джейми Бернс | Изучение SQL | Medium

Различия между UNION и UNION ALL и способы использования UNION для оптимизации ваших запросов с на Unsplash

Очень часто при работе с данными в SQL Server возникает желание объединить разные наборы результатов.

Изучив INNER и LEFT соединения, вы, вероятно, научитесь использовать UNION, но в…

Автор Jamie Burns

246 Последователи

· Автор для

Инженер-программист, основатель бунгало64 Технологии

Еще от Джейми Бернса и Изучение SQL

Джейми Бернс

в

Как использовать Enums при использовании Entity Framework Core с C#

Давайте посмотрим на пару различных способов моделирования перечислений и как мы может предварительно заполнить нашу базу данных этими значениями

·13 минут чтения·23 февраля

Джош Берри

в

5 самых сложных задач в SQL

С реалистичными примерами

900 05

5 минут чтения·25 августа 2022 г.

Зак Куинн

в

5 достойных портфолио идей проектов SQL для начинающих

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

·7 минут чтения·31 августа 2022 г.

Джейми Бернс

in

Пошаговое руководство по функциям Azure

От разработки и тестирования до развертывания — мы рассмотрим, что такое функции Azure и как начать работу с ними.

·20 минут чтения·27 апреля

Просмотреть все от Jamie Burns

Рекомендовано на Medium

Эндрю Кортер

в

Is Star Schema Dead?

Схема «звезда» уже несколько десятилетий используется в хранилищах и витринах данных. Хранилище дешевеет, не пора ли двигаться дальше?

·3 минуты чтения·2 января

Хузайфа Захур

Подготовка к собеседованию по SQL: сколько вам действительно нужно знать для технических гигантов?

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

Читайте примеры и запросы для…

9 минут чтения·28 апреля

Списки

Выбор персонала

302 истории·64 сохранения

Abdelilah MOULIDA

90 002 3 хитрых SQL-запроса решены!!

Объяснение подхода к решению нескольких сложных запросов SQL.

·3 мин чтения·13 января

Жоао Маркес @ Data Beyond Ltd

SQL Like a Pro: настройка запросов на примере

Если вам надоели запросы, которые выполняются часами… это для ты!

· 5 мин. Читать · февраль

PRAVEEN KURAPATI

Оптимизировать производительность SQL Запрос с использованием CTE

CTE — это как легкие, ожидание его — оставшихся временных таблиц, которые делают запрос настолько проще. Но это не просто временные таблицы  — они…

5 минут чтения·6 апреля

Abdelilah MOULIDA

6 Методы оптимизации запросов SQL!!

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

Логика запроса…

·3 минуты чтения·25 января

См. дополнительные рекомендации

Статус

Карьера

Преобразование текста в речь

Разница между UNION и UNION ALL

Последнее изменение: 22 октября 2019 г.

UNION и UNION ALL — это операторы SQL, используемые для объединения двух или более наборов результатов. Это позволяет нам написать несколько операторов SELECT, получить желаемые результаты, а затем объединить их вместе в окончательный унифицированный набор.

Основное различие между UNION и UNION ALL заключается в следующем:

  • UNION: сохраняет только уникальных записей
  • UNION ALL: хранит все записи, включая дубликаты

СОЕДИНЕНИЕ ВСЕ Разница

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

СОЕДИНЕНИЕ

СОЕДИНЕНИЕ ВСЕ

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

*Примечание. В обоих этих примерах имена полей из первого оператора SELECT сохраняются и используются в качестве имен полей в результирующем наборе. При желании их можно изменить позже.

ОБЪЕДИНЕНИЕ данных

UNION или UNION ALL имеют одинаковые основные требования к объединяемым данным:

  1. В каждом операторе SELECT для объединения должно быть получено одинаковое количество столбцов.
  2. Полученные столбцы должны быть в одном и том же порядке в каждом операторе SELECT.
  3. Полученные столбцы должны иметь схожие типы данных.