Master-X
Форум | Новости | Статьи
Главная » Форум » Программинг, Скрипты, Софт, Сервисы » 
Тема: Left join в запросе mysql
цитата
19/07/08 в 23:24
 Sterx
есть запрос вида
select * from $users LEFT JOIN $general ON ($users.user_id=$general.gen_id)
прекрасно выдергивает объединенные данные
однако есть таблица скажем $category,которая также коррелирует с $users
по какому либо полю.
можно сделать 2 раза LEFT JOIN, чтобы получить объединенные данные из 3 таблиц?
цитата
19/07/08 в 23:40
 Heavy
join-ов можно делать сколько угодно и каких угодно, хоть на одни и теже таблицы (главное в алиасах не запутатся и не отсеить нужные строки). все зависит от задачи - что нужно получить на выходе. соответсвенно тебе может подойти и два раза джойн, а может только union.

приведи "на пальцах" таблицы что имеются и что нужно получить в результате.

select *
from $users
LEFT JOIN $general ON ($users.user_id=$general.gen_id)
LEFT JOIN $category ON ($users.cat_id=$category.cat_id)

джойны возможно придется внешние ставить (LEFT OUTER JOIN) что бы не терять записи, также * расшифровать, если есть одинаковые имена полей
цитата
19/07/08 в 23:55
 Sirgey
Не в тему: Не увлекайся с джоинами. Сделай несколько ограниченных выборок.

Mysql сильно тупит когда надо делать джоин на большой выборке, так как перед этим он копирует все данные во временную таблицу. Если у тебя N,M,L строк - в каждой таблице, то каждый запрос - пересоздание N*M*L строчной таблицы. Жопа короче.
цитата
19/07/08 в 23:59
 Sterx
спасибо
избавился от лишних запросов icon_smile.gif
цитата
20/07/08 в 00:00
 Sterx
у меня небольшие выборки
но данные сгруппированы по куче таблиц
вот и пытаюсь оптимизировать
цитата
20/07/08 в 00:49
 Sha
...Умники блин...
Heavy писал:
джойны возможно придется внешние ставить (LEFT OUTER JOIN) что бы не терять записи, также * расшифровать, если есть одинаковые имена полей

LEFT JOIN == LEFT OUTER JOIN по определению.
Sirgey писал:

Mysql сильно тупит когда надо делать джоин на большой выборке, так как перед этим он копирует все данные во временную таблицу. Если у тебя N,M,L строк - в каждой таблице, то каждый запрос - пересоздание N*M*L строчной таблицы. Жопа короче.

Ага. Щас.
цитата
20/07/08 в 09:29
 Sirgey
icon_smile.gif
Sha, посмотри статус у процесса мускулёвого который делает JOIN на большой выборке. Он секунд несколько будет висеть в копировании данных во временную таблицу. Тут я имел ввиду реально большие таблицы. Если размер - пару сотен или тысяча - другая строк - это не большая таблица icon_smile.gif
цитата
20/07/08 в 10:30
 Heavy
Sirgey писал:

Sha, посмотри статус у процесса мускулёвого который делает JOIN на большой выборке.

а можно структуру таблиц, индексов и запроса привести?
временные таблицы в данном случае будут только если мускуль индексами воспользоватся не сможет. простейший двойной джойн, как привел ТС, который делает самую примитивную связку по ключу, никаких временных таблиц не породит даже на многомилионных таблицах.
цитата
20/07/08 в 11:52
 Sha
Вот вот.
Дело в том, что вопреки школьному мнению, что мускуль сначала создаёт прямое произведение, а потом на нём делает чёс по where, мускуль поступает как раз наоборот.
И дело даже не в наличии индексов. Просто мускуль писали люди которые думали что делали.
цитата
20/07/08 в 20:06
 Sirgey
И вы мне говорите про "Умников"? icon_smile.gif

Мускуль классная БД. Но работает она медленно, и кроме того, под нагрузкой возможны блокировки. Джоины, вопреки уверениям разработчиков и всех остальных приводят к созданию временных таблиц. И препираниями на форуме вы этого не отмените, я это постоянно вижу в списке процессов мускульном. (show [full] processlist)

На маленьких выборках и без нагрузки это проскакивает и не заметно. Но чем больше растёт кол - во строк - тем более это заметно. На больших выборках под нагрузкой просто сервак на несколько секунд блокируется.

Индексы не помогают. Оптимизация тоже. Надо просто отказаться от джоина и сделать 2 - 3 выборки отдельных. Естественно надо правильно выстроить запросы, чтобы минимизировать кол - во обрабатываемых строк.

Структуру я не могу привести. Это структуры работы нескольких социальньных сетей и партнёрок. Не я их писал, но лечить потом мне приходилось.
цитата
20/07/08 в 22:02
 xreload
Временная таблица при использовании JOIN создается по неиндексированным полям,в противном случае не создается.
цитата
20/07/08 в 23:25
 Heavy
Sha писал:

Дело в том, что вопреки школьному мнению, что мускуль сначала создаёт прямое произведение, а потом на нём делает чёс по where, мускуль поступает как раз наоборот.

0. "прямое произведение" штука скорее асбстрактная в данном случае и не следует ее восспринимать, как временную таблицу, т.к. они (эти "временные" таблицы) уже существуют - индексы ;)
1. для шибкозаумных запросов, где по-вашему мнению мускуль может тупить и не использовать индекс, есть опции принудительного использования требуемых индексов.
2. речь шла не о "чесе" через where, а именно о join по ключам.
3. один where другому where рознь, в более-менее продуманной базе и запросох перебора базы и создания временных таблиц не происходит - идет тупой пробег по индексу.
4. к временыым таблицам в большинстве случаев приводят только подзапросы, сортировки/группировки/соединения по неиндексу или вычисляемым полям. и то в некоторых случаях можно вполне удовлетворится просто полным перебором, зазря не перегружая машину.


Эта страница в полной версии