Когда я оптимизирую свои 2 одиночных запроса, которые будут выполняться менее чем за 0,02 секунды, а затем UNION, результирующий запрос займет более 1 секунды. Кроме того, UNION ALL занимает больше времени, чем UNION DISTINCT. Я бы предположил, что разрешение дубликатов сделает запрос быстрее и не медленнее. Неужели мне просто лучше работать с двумя запросами отдельно? Я бы предпочел использовать UNION.
Почему запросы UNION так медленны в MySQL?
Ответ 1
Когда я оптимизирую свои 2 одиночных запроса для запуска менее чем за 0,02 секунды, а затем их UNION, результирующий запрос занимает более 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
Кроме того, a
UNION ALL
занимает больше времени, чем aUNION DISTINCT
. Я бы предположил, что дублирование позволит сделать запрос быстрее и не медленнее.
Это также связано с ORDER BY
. Сортировка меньшего набора быстрее, чем более крупная.
Неужели мне просто лучше работать с двумя запросами отдельно? Я бы предпочел использовать
UNION
Вам нужен результирующий набор для сортировки?
Если нет, просто избавьтесь от окончательного ORDER BY
.
Ответ 2
Догадка: Поскольку вы запрашиваете одну таблицу с двумя объединениями, возможно, что mysql испытывает трудности с выбором стратегии блокировки для таблицы или пытается кэшировать, что здесь не работает, поскольку вы запрашиваете непересекающиеся наборы, пытается многопоточно доступ (очень разумный), но работает с некоторыми проблемами блокировки/ concurrency/файлов.
В союзахтакже обычно может использоваться более высокий уровень безопасности, поскольку эти два выбора должны быть согласованными. Если вы помещаете их в отдельные транзакции, они этого не делают.
Эксперимент: Сделайте дубликат таблицы и соедините их. Если я прав, это должно быть быстрее.
Возможное решение: Разделите один файл на несколько файлов, чтобы обеспечить лучшие стратегии concurrency. Это не должно/не должно помочь в устранении проблем, но исключает проблемы многопоточности/поиска в базе данных.
Было бы полезно знать, какой механизм хранения вы используете.
Ну только мои 2 цента. Не могу проверить это здесь прямо сейчас.
Ответ 3
Может быть, вы измеряете время отклика, а не время для извлечения всех данных?