Когда использовать direct_join? - PullRequest
3 голосов
/ 13 июля 2011

В каком порядке MySQL объединяет таблицы, как он выбирается и когда пригодится STRAIGHT_JOIN?

Ответы [ 3 ]

2 голосов
/ 22 июля 2011

MySQL может выполнять только вложенные циклы (возможно, с использованием индексов), поэтому, если обе таблицы объединения проиндексированы, время для соединения вычисляется как A * log(B), если A лидирует, и B * log(A), если B является ведущим.

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

Существуют и другие факторы, влияющие на производительность соединения,такие как WHERE условия, ORDER BY и LIMIT предложения и т. д. MySQL пытается предсказать время для заказов на объединение, и, если статистика актуальна, это хорошо.

STRAIGHT_JOINполезно, когда статистика не точна (скажем, естественно искажена) или в случае ошибок в оптимизаторе.

Например, следующее пространственное соединение:

SELECT  *
FROM    a
JOIN    b
ON      MBRContains(a.area, b.area)

подвергаетсяобмен соединениями (меньшая таблица становится ведущей), однако MBRContains не преобразуется в MBRWithin, и результирующий план не использует индекс.

В этом случае следует явно установить соединениезаказать тебяпеть STRAIGHT_JOIN.

2 голосов
/ 22 июля 2011

Как уже говорили другие об оптимизаторе и о том, какие таблицы могут соответствовать критериям для небольших наборов результатов, но это может не всегда работать.Поскольку я работал с правительственной базой данных контрактов / грантов.В таблице было около 14 с лишним миллионов записей.Тем не менее, в нем также было более 20 таблиц поиска (штаты, округа Конгресса, тип бизнес-классификации, этническая принадлежность владельца и т. Д.)

В любом случае для этих небольших таблиц соединение использовало один из небольших поисков, возвращаясь кмастер таблицы, а затем присоединяется ко всем остальным.Он проверил базу данных и отменил запрос через 30+ часов.Поскольку моя основная таблица была указана в списке ПЕРВЫЙ, а все последующие были просмотрены и присоединены к ПОСЛЕ, просто добавление STRAIGHT_JOIN вверху FORCED упорядочило список, который я перечислил, и сложный запрос снова выполнялся примерно через 2 часа (ожидаемый для всего, что он должен был сделать).

Поднимите все, что от вас зависит, со всеми последующими дополнениями, которые я позже обнаружил, безусловно, поможет.

1 голос
/ 22 июля 2011

Порядок таблиц определяется оптимизатором.Straight_join пригодится, когда оптимизатор делает это неправильно, что не так часто.Я использовал его только один раз в большом соединении, когда оптимизатор дал одну конкретную таблицу на первом месте в соединении (я видел это в команде объяснения select), поэтому я поместил таблицу так, чтобы она позже объединялась в соединении.Это помогло много ускорить запрос.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...