Задавайте вопросы, мы ответим
Вы не зашли.
Такой вопрос назрел.
К примеру, есть две таблицы
t1 с полями f1,f2,f3 и
t2 с полями f4,f5,f6 и индексом поля f5
Если джоинить таблицы по полям f5=f1, используется индекс поля f5, но если в WHERE присутвует условие f6=X, то это поле можно добавить в индекс поля f5 или нужно создать новый индекс? Или для этого поля уже не будет использоваться никакой индекс?
Неактивен
Он при JOIN сначала ищет значение f5, равное f1, затем нужно значение f6. В этом случае подойдет составной индекс KEY(f5,f6). Надо конечно убедиться, что JOIN именно в этом порядке будет выполняться. WHERE часто перетягивает на себя и MySQL начнет выполнять JOIN начиная со второй таблицы. Тогда key(f6), а в первой key(f1).
Неактивен
Хм, интересная новость на счёт WHERE... А никак не удастся заставить обрабатывать джоины именно в указанном порядке? Потому-что в реальном запросе джоинятся 7 таблиц, а WHERE фильтрует записи первых двух таблиц.
Неактивен
Посмотрите EXPLAIN как оптимизатор решил выполнять Ваш запрос. Если не нравится, напишите SELECT STRAIGHT_JOIN ..., тогда JOIN будет в порядке следования таблиц
Неактивен
Т.е. в эксплейне показывается тот порядок, который используется при работе запроса?
Ок, а есть гарантии, что этот порядок не изменится со временем, скажем, из-за глобального потепления или неправильной позиции звёзд?))))
Неактивен
Гарантия есть, только если используете STRAIGHT_JOIN. Если не используете, то оптимизатор вправе каждый раз выбирать порядок, исходя из статистики таблиц (может также зависеть о значения констант в запросе). Пример для последнего поведения такой: У Вас есть WHERE age = -100, оптимизатор знает, что в таблице минимальное значение age 10, поэтому WHERE сразу даст пустое множество и с него легче начать обработку. Если WHERE age=20 дает много результатов, то оптимизатор может начать с другой таблицы, в которой условие WHERE более конкретно.
Неактивен
Ясно, спасибо
Неактивен
Хм, попытался применить STRAIGHT_JOIN вместо LEFT JOIN, так база ругнулась
#1062 - Duplicate entry
Что это может означать? Конечно у меня много записей t2.t1_id = t1.id, неужели из-за этого?
Неактивен
Нет. В этом случае ошибка была бы другой. Что-то типа неопределенность в имени столбца.
Скорее всего дело в том, что STRAIGHT_JOIN аналогичен JOIN, а не LEFT JOIN, т.е. не включает строки не имеющие соответствия.
Неактивен
STRAIGHT_JOIN это не вид JOIN, а специальный оператор, который надо указывать сразу после SELECT для того, чтобы объединение шло в том же порядке
Неактивен
Я удаляю из нескольких таблиц сразу и выборка записей происходит по джоинам. Эксплейн селекта такой выборки показал неправильный порядок, STRAIGHT_JOIN решил этот вопрос. Как быть с удалением? По идее, оптимизатор тоже неправильно строит порядок джоинов. Как быть?
Неактивен
Попробуйте такой синтаксис:
Неактивен
Судя по всему, не помогло, ибо запрос очень долго выполняется, либо я его не правильно составил. У меня используется 4 таблицы. При попытке запустить запрос
DELETE a,b,c,d FROM a USING STRAIGHT_JOIN b,c,d ...
получаю ошибку, а запрос
DELETE FROM a USING STRAIGHT_JOIN b,c,d ...
вродь запустился, но по времени работает столько же, сколько и без STRAIGHT_JOIN.
Из таблицы `a` выбираем записи по константе, а остальные соединяются по ключам.
Неактивен
попробуйте
DELETE FROM a USING a STRAIGHT_JOIN b ON ... STRAIGHT_JOIN c ON ... STRAIGHT_JOIN d ON ...
Неактивен
На такой запрос сервер ругнулся синтаксической ошибкой начиная с "ON ... STRAIGHT_JOIN c ON ... STRAIGHT_JOIN d ON ..."
Уважаемые, ещё будут идеи?
Неактивен
А так:
DELETE a FROM a STRAIGHT_JOIN b ON ... STRAIGHT_JOIN c ON ... STRAIGHT_JOIN d ON ...
?
Неактивен
На оба варианта у меня не возникает синтаксической ошибки, mysql-5.0.22
mysql> DELETE FROM users USING users STRAIGHT_JOIN u ON u.id=users.id STRAIGHT_JOIN xx ON xx.i=u.id;
Query OK, 0 rows affected (0.01 sec)
mysql> DELETE users FROM users STRAIGHT_JOIN u ON u.id=users.id STRAIGHT_JOIN xx ON xx.i=u.id;
Query OK, 0 rows affected (0.00 sec)
Неактивен
Странно однако на счёт синтаксиса.. У меня 5.0.51а. В общем, решил проблему циклами на стороне клиента.
Неактивен