programmer
С нами с 08.12.02
Сообщения: 7613
Рейтинг: 5760
|
Добавлено: 19/07/08 в 23:24 |
есть запрос вида
select * from $users LEFT JOIN $general ON ($users.user_id=$general.gen_id)
прекрасно выдергивает объединенные данные
однако есть таблица скажем $category,которая также коррелирует с $users
по какому либо полю.
можно сделать 2 раза LEFT JOIN, чтобы получить объединенные данные из 3 таблиц?
|
|
|
|
С нами с 01.03.06
Сообщения: 629
Рейтинг: 620
|
Добавлено: 19/07/08 в 23:40 |
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) что бы не терять записи, также * расшифровать, если есть одинаковые имена полей
|
|
|
|
С нами с 16.04.05
Сообщения: 754
Рейтинг: 352
|
Добавлено: 19/07/08 в 23:55 |
Не в тему: Не увлекайся с джоинами. Сделай несколько ограниченных выборок.
Mysql сильно тупит когда надо делать джоин на большой выборке, так как перед этим он копирует все данные во временную таблицу. Если у тебя N,M,L строк - в каждой таблице, то каждый запрос - пересоздание N*M*L строчной таблицы. Жопа короче.
|
|
|
|
programmer
С нами с 08.12.02
Сообщения: 7613
Рейтинг: 5760
|
Добавлено: 19/07/08 в 23:59 |
спасибо
избавился от лишних запросов
|
|
|
|
programmer
С нами с 08.12.02
Сообщения: 7613
Рейтинг: 5760
|
Добавлено: 20/07/08 в 00:00 |
у меня небольшие выборки
но данные сгруппированы по куче таблиц
вот и пытаюсь оптимизировать
|
|
|
|
С нами с 11.06.03
Сообщения: 1266
Рейтинг: 950
|
Добавлено: 20/07/08 в 00:49 |
...Умники блин...
Heavy писал: | джойны возможно придется внешние ставить (LEFT OUTER JOIN) что бы не терять записи, также * расшифровать, если есть одинаковые имена полей |
LEFT JOIN == LEFT OUTER JOIN по определению.
Sirgey писал: |
Mysql сильно тупит когда надо делать джоин на большой выборке, так как перед этим он копирует все данные во временную таблицу. Если у тебя N,M,L строк - в каждой таблице, то каждый запрос - пересоздание N*M*L строчной таблицы. Жопа короче.
|
Ага. Щас.
|
|
|
|
С нами с 16.04.05
Сообщения: 754
Рейтинг: 352
|
Добавлено: 20/07/08 в 09:29 |
Sha, посмотри статус у процесса мускулёвого который делает JOIN на большой выборке. Он секунд несколько будет висеть в копировании данных во временную таблицу. Тут я имел ввиду реально большие таблицы. Если размер - пару сотен или тысяча - другая строк - это не большая таблица
|
|
|
|
С нами с 01.03.06
Сообщения: 629
Рейтинг: 620
|
Добавлено: 20/07/08 в 10:30 |
Sirgey писал: |
Sha, посмотри статус у процесса мускулёвого который делает JOIN на большой выборке. |
а можно структуру таблиц, индексов и запроса привести?
временные таблицы в данном случае будут только если мускуль индексами воспользоватся не сможет. простейший двойной джойн, как привел ТС, который делает самую примитивную связку по ключу, никаких временных таблиц не породит даже на многомилионных таблицах.
|
|
|
|
С нами с 11.06.03
Сообщения: 1266
Рейтинг: 950
|
Добавлено: 20/07/08 в 11:52 |
Вот вот.
Дело в том, что вопреки школьному мнению, что мускуль сначала создаёт прямое произведение, а потом на нём делает чёс по where, мускуль поступает как раз наоборот.
И дело даже не в наличии индексов. Просто мускуль писали люди которые думали что делали.
|
|
|
|
С нами с 16.04.05
Сообщения: 754
Рейтинг: 352
|
Добавлено: 20/07/08 в 20:06 |
И вы мне говорите про "Умников"?
Мускуль классная БД. Но работает она медленно, и кроме того, под нагрузкой возможны блокировки. Джоины, вопреки уверениям разработчиков и всех остальных приводят к созданию временных таблиц. И препираниями на форуме вы этого не отмените, я это постоянно вижу в списке процессов мускульном. (show [full] processlist)
На маленьких выборках и без нагрузки это проскакивает и не заметно. Но чем больше растёт кол - во строк - тем более это заметно. На больших выборках под нагрузкой просто сервак на несколько секунд блокируется.
Индексы не помогают. Оптимизация тоже. Надо просто отказаться от джоина и сделать 2 - 3 выборки отдельных. Естественно надо правильно выстроить запросы, чтобы минимизировать кол - во обрабатываемых строк.
Структуру я не могу привести. Это структуры работы нескольких социальньных сетей и партнёрок. Не я их писал, но лечить потом мне приходилось.
|
|
|
|
С нами с 19.11.03
Сообщения: 3973
Рейтинг: 2362
|
Добавлено: 20/07/08 в 22:02 |
Временная таблица при использовании JOIN создается по неиндексированным полям,в противном случае не создается.
|
|
|
|
С нами с 01.03.06
Сообщения: 629
Рейтинг: 620
|
Добавлено: 20/07/08 в 23:25 |
Sha писал: |
Дело в том, что вопреки школьному мнению, что мускуль сначала создаёт прямое произведение, а потом на нём делает чёс по where, мускуль поступает как раз наоборот. |
0. "прямое произведение" штука скорее асбстрактная в данном случае и не следует ее восспринимать, как временную таблицу, т.к. они (эти "временные" таблицы) уже существуют - индексы ;)
1. для шибкозаумных запросов, где по-вашему мнению мускуль может тупить и не использовать индекс, есть опции принудительного использования требуемых индексов.
2. речь шла не о "чесе" через where, а именно о join по ключам.
3. один where другому where рознь, в более-менее продуманной базе и запросох перебора базы и создания временных таблиц не происходит - идет тупой пробег по индексу.
4. к временыым таблицам в большинстве случаев приводят только подзапросы, сортировки/группировки/соединения по неиндексу или вычисляемым полям. и то в некоторых случаях можно вполне удовлетворится просто полным перебором, зазря не перегружая машину.
|
|
|
|