Почему запросы UNION в MySQL такие медленные? - PullRequest
10 голосов
/ 15 мая 2009

Когда я оптимизирую два отдельных запроса для выполнения менее чем за 0,02 секунды, а затем ОБЪЕДИНЯЮ их, результирующий запрос занимает более 1 секунды для выполнения. Кроме того, UNION ALL занимает больше времени, чем UNIST DISTINCT. Я бы предположил, что если разрешить дубликаты, запрос будет выполняться быстрее, а не медленнее. Неужели мне просто лучше запустить 2 запроса отдельно? Я бы предпочел использовать UNION.

Ответы [ 3 ]

15 голосов
/ 16 мая 2009

Когда я оптимизирую два отдельных запроса для выполнения менее чем за 0,02 секунды, а затем ОБЪЕДИНЯЮ их, результирующий запрос занимает более 1 секунды.

Включают ли ваши запросы ORDER BY … LIMIT пункты?

Если вы поставите ORDER BY … LIMIT после UNION, он будет применен ко всему UNION, и индексы в этом случае использовать нельзя.

Если id является первичным ключом, этот запрос будет мгновенным:

SELECT  *
FROM    table
ORDER BY id
LIMIT 1

, но этот не будет:

SELECT  *
FROM    table
UNION ALL
SELECT  *
FROM    table
ORDER BY id
LIMIT 1

Кроме того, UNION ALL занимает больше времени, чем UNION DISTINCT. Я бы предположил, что если разрешить дубликаты, запрос будет выполняться быстрее, а не медленнее.

Похоже, это также связано с ORDER BY. Сортировка меньшего набора выполняется быстрее, чем большего.

Неужели мне лучше просто выполнить 2 запроса отдельно? Я бы предпочел использовать UNION

Вам нужно отсортировать полученный набор?

Если нет, просто избавьтесь от финала ORDER BY.

4 голосов
/ 15 мая 2009

Догадка: Поскольку вы запрашиваете одну таблицу с двумя объединениями, может случиться так, что mysql испытывает трудности с выбором стратегии блокировки для таблицы, или он пытается выполнить некоторое кэширование, которое здесь не работает, так как вы запрашиваете непересекающиеся множества, пытается многопоточность доступ (очень разумный), но сталкивается с некоторыми проблемами блокировки / параллелизма / поиска файла ..

Союзы

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

Эксперимент: Сделайте копию таблицы и объедините их. Если я прав, это должно быть быстрее.

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

Было бы полезно узнать, какой механизм хранения вы используете.

Ну, только мои 2 цента. Не могу проверить это здесь прямо сейчас.

0 голосов
/ 16 сентября 2009

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

...