Почему Запросы на объединение являются настолько медленными в MySQL?

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

11
задан geisterfurz007 Stop this chaos 27 November 2019 в 06:11
поделиться

4 ответа

Относительно UNION

  • UNION DISTINCT (значение по умолчанию для UNION) обязательно медленнее, потому что оно должно собрать два результата, затем dedup. Однако с тех пор там меньше возвращается клиенту, там мог некоторая компенсация там.
  • , Пока последние версии, весь UNIONs не включили временную таблицу для сбора результатов, следовательно UNION было обязательно медленнее, чем два отдельных SELECTs. Недавно, (MySQL 5.7, MariaDB 10.1) некоторые случаи UNION ALL были улучшены, чтобы освободить данные из одного SELECT прямо клиенту, затем поставить другим.
  • SELECT .. UNION SELECT .. ORDER BY .. эквивалентно [1 120]
    (SELECT .. UNION SELECT ..) ORDER BY .. - это
    (SELECT ..) UNION (SELECT .. ORDER BY ..) - не это
    всегда Предлагает использовать parens вокруг каждого SELECT.
  • Сортировка (через [1 112]) может занимать дополнительное время для любого (выбор или объединение), это присоединено. Это очень маловероятно для взятия меньше время. Проще говоря, Оптимизатор имеет целью делать то независимо от того, что является самым быстрым, который мог бы , оказываться, быть отсортирован.
  • Все эти операторы относятся к InnoDB; MyISAM, который не поддерживается очень, может пропускать некоторую недавнюю оптимизацию.
  • Иногда сингл SELECT с OR может быть ускорен, превратив его в UNION, таким образом, позволив двум индексам использоваться.

Относительно тестирования:

  • время А 0,001 запахов как Вы выполнило запрос прежде, и результат кэшируется в "Кэше запроса". Избегайте этого путем выключения королевского адвоката или добавления SQL_NO_CACHE.
  • Выбор WHERE flag = true (or false) имеет несколько случаев: flag индексируется? flag почти всегда одно из тех значений? В [1 128], что случай, индекс будет использоваться, и , вероятно быстрее, чем другой случай.
  • , Если Вы не соглашаетесь с каким-либо из моих операторов, обеспечьте рабочий пример об обратном.
3
ответ дан 3 December 2019 в 04:33
поделиться

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

Используя оператор Where на результате сгруппированных результатов является слишком дорогим, потому что Вы воздействуете на большее количество внутренних результатов, чем Вам нужно. Кроме того, оптимизация механизма базы данных can’t быть обработанной — результаты не имеет ничего общего.

проверка эта ссылка для деталей https://dzone.com/articles/performance-tip-for-tuning-sql-with-union

0
ответ дан 3 December 2019 в 04:33
поделиться

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

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

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

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

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

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

4
ответ дан 3 December 2019 в 04:33
поделиться

Когда я оптимизирую свои 2 отдельных запроса для выполнения менее чем за 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 . Сортировка меньшего набора происходит быстрее, чем большего.

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

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

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

17
ответ дан 3 December 2019 в 04:33
поделиться
Другие вопросы по тегам:

Похожие вопросы: