Задавайте вопросы, мы ответим
Вы не зашли.
Страниц: 1
Товарищи, столкнулся со следующей проблемой.
Есть составной ключ, пусть (id, blocked). Нужен JOIN с другой таблицей по id, но еще - условие WHERE blocked = 0.
Пишет, что используется только левая часть индекса (id, то есть).
Думал-думал, почему.. Пришел к выводу: оттого, что JOIN воспринимается как запрос вида IN(..).
Выходит, при JOIN можно использовать только левую часть индекса, а остальное отваливается, т.к. JOIN воспринимается как range.
Так получается?
Если да, то досадно т.к. от этой таблицы было нужно лишь количество записей (там группировка потом по другой таблице), просто с условием на blocked.
Получается, из-за этого условия придется для каждой записи на диск лазить, и ничего не поделаешь. Прямо не знаю, хоть индекс во временную таблицу в памяти загоняй..
Неактивен
LazY написал:
Думал-думал, почему.. Пришел к выводу: оттого, что JOIN воспринимается как запрос вида IN(..).
Выходит, при JOIN можно использовать только левую часть индекса, а остальное отваливается, т.к. JOIN воспринимается как range.
Так получается?
Таблицы связаны по id на сколько я понимаю. Тогда при использовании id ты выдергиваешь запись из другой таблицы и помещаешь полученный результат (запись из первой таблицы + запись из второй) во временную таблицу. Понятно, что правая часть индекса из первой таблицы не используется при работе с временной таблицей.
Сделай индекс (blocked, id)
Неактивен
От себя добавлю, что это, кажется, тот случай, когда условие надо засунуть
в ON, т.е. ON (this.id = that.id AND that.blocked = 0). Подозреваю, что в этом
случае индекс будет использоваться целиком.
Неактивен
vasya написал:
при использовании id ты выдергиваешь запись из другой таблицы и помещаешь полученный результат (запись из первой таблицы + запись из второй) во временную таблицу. Понятно, что правая часть индекса из первой таблицы не используется при работе с временной таблицей.
Так мне во временной таблице правая часть и не нужна. Но я надеялся, что перед созданием временной таблицы будет учтено условие WHERE (а я верю, что это перед созданием временной таблицы делается), которое сможет посмотреть в правую часть индекса и на диск не полезет. А получается по-другому.
Индекс (blocked, id) тут вряд ли поможет, т.к. JOIN-то по id - наверняка MySQL не сможет для JOIN использовать правую часть индекса.
paulus написал:
От себя добавлю, что это, кажется, тот случай, когда условие надо засунуть
в ON, т.е. ON (this.id = that.id AND that.blocked = 0).
Мысль интересная, попробую... (тогда получится, что MySQL один и тот же индекс может использовать только для одной операции; т.е. если им пользуется JOIN, то WHERE в него уже смотреть не будет)
Неактивен
paulus написал:
это, кажется, тот случай, когда условие надо засунуть
в ON, т.е. ON (this.id = that.id AND that.blocked = 0).
Так и есть! Спасибо, получилось.
(Примечание: скобки после ON не нужны)
Неактивен
В недрах памяти сидит, что вроде как все ON (условие) преобразуются во WHERE (условие) оптимизатором. Из данного случая получается, что это не совсем так. Я как то натыкался на аналогичный момент. Кто-нибудь может популярно объяснить в чем тонкость?
С Новым Годом, кстати, коллеги
Успешной работы
Неактивен
Я бы думал наоборот, что условие WHERE преобразуется в JOIN. Например, такое бывает, если JOIN без условия, а соответствующее условие есть в WHERE. Однако по своей сути JOIN и WHERE две совершенно разные операции и если у каждой из них есть условие, оптимизатор может и ничего не переносить. Это общее свойство оптимизатора MySQL, что он ничего не делает, кроме нескольких заранее известных ему частных случаев.
C Новым годом!
Неактивен
Пошло это, по всей видимости вот откуда. Вот страница из доки (версия значения не имеет) - http://dev.mysql.com/doc/refman/5.5/en/ … ation.html
п.3 -
The LEFT JOIN condition is used to decide how to retrieve rows from table B. (In other words, any condition in the WHERE clause is not used.)
Вот ее перевод на mysql.ru (далее растиражированный по всем интернетам) - http://www.mysql.ru/docs/man/LEFT_JOIN_ … ation.html
п.3 -
Все условия LEFT JOIN перемещаются в предложение WHERE.
хе-хе
Неактивен
Да, я знал, что надо всегда читать оригинал
Неактивен
Страниц: 1