Статьи

Как оптимизировать MySQL UNION для высокой скорости

Есть два способа ускорить UNION в базе данных MySQL. Во-первых, используйте UNION ALL, если это вообще возможно, а во-вторых, попытайтесь снизить ваши условия.

1. UNION ALL намного быстрее, чем UNION

Как работает UNION? Представьте, что у вас есть два стола для рубашек. Таблица short_sleeve выглядит следующим образом:

blue
green
gray
black

И long_sleeve другой, который выглядит так:

red
green
yellow
blue

Связанный: Почему Генералы Лучше в Масштабировании Сети

Если вы ОБЪЕДИНИТЕ эти две таблицы, сначала MySQL отсортирует объединенный набор во временную таблицу следующим образом:

black
blue
blue
gray
green
green
red
yellow

После того, как это сделано, он может легко удалить дубликаты синего и дубликата зеленого для этого результирующего набора:

black
blue
gray
green
red
yellow

Смотрите также: Mythical MySQL DBA — талант засухи .

Почему он это делает? UNION определяется таким образом в SQL. Дубликаты должны быть удалены, и для движка MySQL это эффективный способ их удаления. Объедините результаты, сортируйте, удаляйте дубликаты и возвращайте набор.


Запросы с помощью UNION могут быть ускорены двумя способами.
Переключитесь на UNION ALL или попробуйте выдвинуть условия ORDER BY, LIMIT и WHERE внутри каждого подзапроса. Вы будете рады, что сделали!

Что если мы сделали UNION ALL? Результат будет выглядеть так:

blue
green
gray
black
red
green
yellow
blue

Прочитайте это: MySQL DBA Интервью и Наем Руководство .

Он не должен сортировать и не должен удалять дубликаты. Если вы представляете себе объединение двух 10 миллионов таблиц строк и не должны сортировать, это ускорение может быть ОГРОМНЫМ.

2. Используйте Push-down Условия для ускорения UNION в MySQL

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

Вот таблица short_sleeve:

blue		2013
green		2013
green		2012
gray		2011
black		2009
black		2011

И таблица long_sleeve выглядит так:

red		2012
red		2013
green		2011
yellow	2010
blue		2011

В 2013 году дизайны могли бы объединить их так:

(SELECT type, release FROM short_sleeve)
UNION
(SELECT type, release FROM long_sleeve);
WHERE release >=2013;

Смотрите также: 5 вещей, смертоносных для масштабируемости и оригинальные 5 вещей, токсичных для масштабируемости . ,

Здесь предложение WHERE работает с этой временной таблицей из 11 записей:

black		2009
black		2011
blue		2011
blue		2013
gray		2011
green		2013
green		2012
green		2011
red		2012
red		2013
yellow	2010

Но было бы намного быстрее перемещать WHERE внутри каждого подзапроса следующим образом:

(SELECT type, release FROM short_sleeve WHERE release >=2013)
UNION
(SELECT type, release FROM long_sleeve WHERE release >=2013);

Это будет работать на комбинированной таблице 3 записи. Быстрее сортировать и удалять дубликаты. Меньший кэш наборов результатов также лучше, обеспечивая выплату дивидендов. Вот что такое оптимизация производительности!

Прочитайте это: RDS или MySQL — 10 вариантов использования .

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

Вы также можете использовать эту оптимизацию для ORDER BY и для условий LIMIT. Сокращая количество записей, возвращаемых КАЖДОЙ ЧАСТЬЮ СОЮЗА, вы сокращаете объем работы, которая происходит на этапе, когда они объединяются.

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