LEFT JOIN или два запроса - что быстрее?

Ashotovich

Новичок
LEFT JOIN или два запроса - что быстрее?

Всем привет.
У меня есть две таблицы: одна - справочник, в котором находятся все типы мероприятий (называется, допустим, at):
Код:
at_id | at_name
---------------------
1     | Aaaaa
2     | Bbbbb
3     | Cccccc
4     | Ddddd
Другая таблица - список проделанных мероприятий (назовем ее ad):
Код:
ad_id | at_id | ad_date
--------------------------
1     | 2     | 2004-01-08
2     | 2     | 2004-01-08
3     | 1     | 2004-01-08
4     | 1     | 2004-01-09
В сводной таблице необходимо вывести список всех типов мероприятий с количеством проделанных по каждому типу:
Код:
at_id | qty
---------------------
1     | 2
2     | 2
3     | 0
4     | 0
Соответственно, наиболее легко это реализуется при помощи одного запроса, использующего LEFT JOIN:
PHP:
SELECT at.at_id, count(ad.at_id) AS qty FROM at LEFT JOIN ad ON ad.at_id=at.at_id GROUP BY at.at_name
Более сложно и, на первый взгляд, "криво" это можно сделать двумя запросами: сначала получаем список типов мероприятий из первой таблицы (at_id, at_name), запихиваем его в двухмерный массив, затем - делаем выборку типов и количеств из второй таблицы и присоединяем результат к уже имеющемуся массиву - в результате выходят те же данные, что и при запросе с применением JOIN.

А вопрос вот в чем: если вторая таблица на миллион-другой записей, не сильно ли будет тормозить JOIN? При малых размерах таблиц все понятно - JOIN и быстрее, и проще. А вот при больших таблицах - будет ли он быстрее?

Заранее спасибо за помощь.
 

Demiurg

Guest
а ты думаешь массив на миллион записей не будет тромозить ?
 

tony2001

TeaM PHPClub
>А вот при больших таблицах - будет ли он быстрее?
однозначно будет.
 

Ashotovich

Новичок
Он не на миллион получится, а на количество типов в справочнике (около десяти). То есть массив будет 10*2, в приведенном примере - 4*2.
 

tony2001

TeaM PHPClub
>>А вот при больших таблицах - будет ли он быстрее?
>однозначно будет.
..при соотв-щих индексах.
 

Falc

Новичок
Demiurg
Ты не понял массива на милион записей не будет.

Ashotovich
Как я пологаю основные затраты процессорного времени при больших таблицах уйдет на просчет count, т.к. каунты будут считаться одни и теже. то разница в скорости будет не большой, причем в пользу LEFT JOIN.
 

tony2001

TeaM PHPClub
>А если индексы построены по каждому полю в отдельности (таблица-тоучавствует в куче разных запросов)?
соотв-щие - это значит _правильные_.
индексы по каждому полю - звучит подозрительно и не означает правильность.
возможно, что в некоторых случаях необходимы составные индексы - это же твоя база, ты и анализируй её.
 

Falc

Новичок
По поводу индексов хочу заметить, что в обоих вариантах они должны быть одинаковые, а именно по полю:
at_id во второй таблице.
Да и групировать надо не по нейму а по id
 

гоша

Guest
если действительно

> количество типов в справочнике (около десяти).

то можно

1) читать весь справочник в хеш (ид => название), а при выводе говорить

while($f=mysql_fetch_assoc($query))
echo $справочник[$f["at_id"]]

то есть примерно то что ты и хотел сначала

2) не делать вообще таблицу справочник, а хранить их в массиве и инклудить его

3) не делать вообще таблицу справочник, а завести enum поле с названиями
 

Falc

Новичок
гоша
>>1)
Лишний запрос к базе и лишний код в скриптах.

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

>>3)
будут проблемы с добавлением новых типов, опятьже на скорости никак не отразится
 

гоша

Guest
т.е., если у него будет простой запрос вместо джойна, то это

> на скорости никак не отразится

уверен? ;)
 

Falc

Новичок
гоша
Извени скорость увеличится на 0.01%, был не прав каюсь
 

Ashotovich

Новичок
Тогда еще один вопрос: JOIN захватывает всю таблицу, или только ее часть, указанную в WHERE?
 

Ashotovich

Новичок
Автор оригинала: Falc
По поводу индексов хочу заметить, что в обоих вариантах они должны быть одинаковые, а именно по полю:
at_id во второй таблице.
Да и групировать надо не по нейму а по id
То есть, если у меня во второй таблице индексы проставлены отдельно по второму и третьему полю (составных индексов нет), то этого достаточно для быстрой работы запроса с JOIN (третье поле там нужно будет при указании WHERE ad.ad_date>...)?
 

Falc

Новичок
Ashotovich
>>То есть, если у меня во второй таблице индексы проставлены отдельно по второму и третьему полю (составных индексов нет), то этого достаточно для быстрой работы запроса с JOIN

Еще раз повторю, для данной выбоки достаточно одного индекса at_id.

>>(третье поле там нужно будет при указании WHERE ad.ad_date>...)?
Да.

>>Тогда еще один вопрос: JOIN захватывает всю таблицу, или только ее часть, указанную в WHERE?

Только часть в зависимости от условия соединения. (условия соединения лучше указывать не в WHERE)
 
Сверху