Задавайте вопросы, мы ответим
Вы не зашли.
Подскажите, пожалуйста, правильно ли я понимаю суть проблемы и возможные пути решения
есть две таблицы
Неактивен
Почему, ну почему все пишут левое объединение там, где место внутреннему
объединению?
Попробуйте:
1. Использовать внутреннее объединение (и всегда-всегда использовать их
кроме случаев, когда внешнее правда нужно);
2. Решить, какая сортировка Вам таки нужна. Если нужна сортировка по имени,
то нужен индекс на (language_id, name).
P.S. Кстати, помимо использования объединения, Вы еще не попробовали FORCE
INDEX, он бы прошел нормально в случае сортировки: по name то у Вас ключ есть.
Неактивен
пробовал
вот
Правильно ли я понимаю, что такое сильное торможение первого связано с тем, что сортировка проводится по таблице, которая была присоединена не в самом начале? То есть всякую сортировку(в большинстве случаев) стоит проводить по полям той таблицы, которая присоединяется первой (идёт в EXPLAIN-е первой)
Неактивен
Давайте я опишу всё более подробно с реальным запросом
в запросе участвуют 3 таблицы
Отредактированно jerry (01.02.2011 21:32:42)
Неактивен
Фраза, обведенная в рамочку, верна отчасти. А отчасти — нет. Нет — потому что
MySQL выбирает порядок таблиц таким образом, чтобы уменьшить время выполнения
запроса. В частности, это относится и к сортировке. Кстати, LEFT JOIN мешают
менять таблицы местами, это тоже надо учитывать.
Что касается запроса — попробуйте рассказать оптимизатору приоритет индексов:
product_description pd FORCE INDEX (language_id): у Вас слишком много индексов
над близкими полями (например, PK начинается на тот же language_id), и оптимиза-
тор может неправильно выбирать индекс для работы с табличкой.
Неактивен
сделал
Отредактированно jerry (01.02.2011 23:26:09)
Неактивен
У Вас уже выбралась pd первой. Сортировки в памяти нет. Я ожидаю, что вот этот запрос
будет работать чрезвычайно быстро.
Если только доп.условия у Вас не такие, что пропускают кучу строк. Если такие — то
MySQL оказывался таки прав, и тогда мы пойдем другим путем (только расскажите,
что это действительно так)
Что касается вспомогательных таблиц — да, разумеется, делают. Это называется денор-
мализацией.
Неактивен
Если только доп.условия у Вас не такие, что пропускают кучу строк. Если такие — то
MySQL оказывался таки прав, и тогда мы пойдем другим путем
получается так, они пропускают много строк.. по сути там единственное условие это pd.language_id = '1'. В таблице всего 4 таких уникальных id, поэтому особого отсева и не происходит в данном случае. Если например поставить pd.language_id = '2', то скорость несколько возрастёт, потому как с language_id=2 всего 10к записей..
Неактивен
Ну вот, то есть MySQL был прав, когда ставил таблички в другом порядке
Тогда есть такой хитрый... ээ... назовем его финт ушами — если нам нужно
всё равно сортировать в памяти — лучше сортировать меньше данных, будет
быстрее. Делайте тогда не SELECT *, а SELECT id ... — у Вас будут отсортиро-
ванные по старому алгоритму id в памяти. Сортировать строки из 4 байт куда
быстрее, чем из 500 (?). К полученному обрезанному LIMIT (!) подзапросу
уже можно будет присоединить реальные данные через JOIN (т.е. сортируете
только id, а данные достаете только те, которые нужно).
Наверное, много слов, проще запросом:
SELECT p.* FROM product p JOIN (SELECT id ... длинный подзапрос) s USING (id).
Неактивен
Честно говоря не уловил мысли. Попробовал сделать несколько запросов, но они вобще не исполняются (как минимуму больше минуты занимают). Не могли бы написать зарос, который подразумевали.
>К полученному обрезанному LIMIT (!) подзапросу
если тут вы подразумевали просто сделать выборку 24 строк из таблицы product_description, отсортированных по name, то ведь тут нету эквивалентности моему запросу -в category_id=4 могут оказаться только продукты чьи имена начинаются с буквы "P", а из таблицы product_description будут выбраны только продукты с именами, начинающимися с первых/последних букв алфавита -соответственно полный запрос вернёт 0 строк..
Скорее всего я просто не понял вашего сообщения -напишите, пожалуйста, запрос
Отредактированно jerry (02.02.2011 13:57:19)
Неактивен
SELECT x.* FROM product x JOIN
(SELECT id
FROM product p
JOIN product_description pd ON ( p.product_id = pd.product_id )
JOIN product_to_category p2c ON ( p.product_id = p2c.product_id )
WHERE p.status = '1'
AND p.date_available <= NOW( )
AND pd.language_id = '1'
AND p2c.category_id = '4'
ORDER BY pd.name DESC
LIMIT 0 , 24) s USING (id) ?
Неактивен
Прошу прощения за отсутствие
попробовал ваш предыдущий запрос (id изменил на product_id только), получилось вот так
Отредактированно jerry (05.02.2011 19:21:26)
Неактивен