Что будет работать быстрее один запрос или несколько?

Теркин

Новичок
Что будет работать быстрее один запрос или несколько?

Есть две таблицы автор(ид_автора, имя_автора) и книги_аврора (ид_автора, имя_книги). Книг у каждого автора много.

Нужно вывести список книг авторов.

Варианты:

1. select автор.имя_автора, книги_аврора.имя_книги from автор, книги_аврора where автор.ид_автора=книги_аврора.ид_автора;

2. select ид_автора, имя_автора from автор
for()
{
select имя_книги from книги_аврора where ид_автора=$ид_автора
}

Что будет работать быстрее 1. или 2.?

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

magic

lancer
1. Налицо неверная логика. Вам следует хорошо обдумать, что вы делаете.
2. Один запрос быстрее.
 

440hz

php.ru
Теркин
1. если авторов и книг ~ 5000 ты не заметишь разницы.
2. оптимизацией надо заниматься тогда - когда тормозит.
3. почему ты озадачился этим вопросом?
 

Теркин

Новичок
Автор оригинала: 440hz
Теркин
1. если авторов и книг ~ 5000 ты не заметишь разницы.
2. оптимизацией надо заниматься тогда - когда тормозит.
3. почему ты озадачился этим вопросом?
1. Но тогда во втором случае будет очень много запросов. Все говорят это вредно. Но я думаю дело не в количестве, а в самих запросах. Просто в первом случае mysql все равно придется обращаться (просматривать) к таблице с книгами столько раз, сколько авторов, или наоборот для каждой книги искать автора в таблице с авторами.
2. Проще при написании скрипта оптимизировать, чем потом переделывать.
3. просто у меня много подобных запросов. Не хотелось бы потом их переписывать.

-~{}~ 23.03.06 05:31:

Написал скриптик для оценки быстродействия
Выводы:
"Два" запроса работают быстрее одного, если количество возвращаемых рядов первого намного меньше второго. Соотношение 50/500 обрабатывается одним запросом в 25 раз медленнее. Но если использовать вместо mysql_query mysql_unbuffered_query, то один запрос будет работать в 10 раз быстрее.

Так как mysql_unbuffered_query нельзя использовать для двух запросов, придется остановиться на первом варианте.
 

Wicked

Новичок
Теркин
во-первых тебе стоит прочитать, что же делает mysql_unbuffered_query().

во-вторых, неплохо бы написать сюда результат работы запроса

explain select автор.имя_автора, книги_аврора.имя_книги from автор, книги_аврора where автор.ид_автора=книги_аврора.ид_автора;
 

magic

lancer
Да Теркин, я бы тоже посмотрел на эти тесты и как это у тебя получился такой разброс.
 

Теркин

Новичок
Автор оригинала: Wicked
Теркин
во-первых тебе стоит прочитать, что же делает mysql_unbuffered_query().
Я знаю, что она делает, если бы не знал, не применял бы. Не нужно думать, что вы умнее всех.

Автор оригинала: Wicked
во-вторых, неплохо бы написать сюда результат работы запроса

explain select автор.имя_автора, книги_аврора.имя_книги from автор, книги_аврора where автор.ид_автора=книги_аврора.ид_автора;
table type possible_keys key key_len ref rows Extra
author ALL PRIMARY NULL NULL NULL 50
books ref id_author id_author 4 author.id_author 500


Автор оригинала: magic
Да Теркин, я бы тоже посмотрел на эти тесты и как это у тебя получился такой разброс.
Тесты простые. Различные варианты этого кода.
PHP:
$time_1 = time();

$g = 10;
while($g--)
{
    $choice = 'select id_author, name_author from author';
    $result = mysql_query($choice);
    $num = mysql_num_rows($result);
    for($i=0; $i<$num; $i++)
    {
        $id_author = mysql_result($result, $i, 'id_author');
        $name_author = mysql_result($result, $i, 'name_author');
        $choice = 'select id_book, name_book from books where id_author="' . $id_author . '"';
        $result_ = mysql_query($choice);
        $num_ = mysql_num_rows($result_);
        for($j=0; $j<$num_; $j++)
        {
            $name_book = mysql_result($result_, $j, 'name_book');
            $id_book = mysql_result($result_, $j, 'id_book');

        }
    }
}
$time_2 = time();
echo $time_1 . '<br>';
echo $time_2 . '<br>';
echo $time_2 - $time_1 . '<br>' . $num . '|' . $num_ . '<br><br>';



$time_1 = time();
$g = 10;
while($g--)
{
    $choice = 'select author.name_author, books.name_book, books.id_book from books, author where books.id_author=author.id_author';
    $result = mysql_unbuffered_query($choice);
    for($i=0; $r = mysql_fetch_row($result); $i++)
    {
    }
}
$time_2 = time();
echo $time_1 . '<br>';
echo $time_2 . '<br>';
echo $time_2 - $time_1 . '<br>' . $i . '<br><br>';
 

Теркин

Новичок
Разброс такой из-за того, что в запросе 'select author.name_author, books.name_book, books.id_book from books, author where books.id_author=author.id_author' большое количество рядов и если их получать через mysql_query() php забьет ими память.
 

Фанат

oncle terrible
Команда форума
а зачем получать такое большое количество рядов? если даже у пхп память забьётся
 

Теркин

Новичок
Дело не в "зачем".
Изначально стояла задача вывести список <select> городов с группировкой по странам в option нужно было выводить id_сртаны + id_города. Стран мало около 10, городов около 5-10 для каждой страны. Проще вывести такой список двумя форами используя два запроса, чем одним и потом проверять изменения id, да и данных в одном запросе будет больше, страны будут повторяться для каждого города. Вот я и решил узнать как будет быстрее. Оказалось что так быстрее не будет в любом случае. Если городов по отношению к странам мало, то два запроса будут работать медленнее, чем один, если много, то проще воспользоваться mysql_unbuffered_query, которая даст выигрыш за счет того, что php не будет дожидаться окончания выполнения запроса и mysql не будет буферизировать результаты запроса.

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

Фанат

oncle terrible
Команда форума
Дело не в "зачем".
Дело в "зачем".
вопросы всегда надо задавать осмысленные и реальные.
Гадать на кофейной гуще тут никто не будет.
Смысл получать в скрипт 5000 наименований - отсутствует.
И обсуждать высосанные из пальца задачи никто не будет.
Проще вывести такой список двумя форами используя два запроса,
неправда.
насколько я понимаю, тебе нужен селект из 100 пунктов вида
Австралия, Аделаида
Австралия, Перт
Австралия, Сидней
так?
это делается одним запросом. ПРОЩЕ.
Но так как таких запросов много, то лучше сразу сделать как нужно.
ТАКИХ запросов больше нет.
все запросы РАЗНЫЕ
и делать надо в каждом случае ИНДИВИДУАЛЬНО.
 

Теркин

Новичок
Автор оригинала: Фанат
Дело в "зачем".
вопросы всегда надо задавать осмысленные и реальные.
Гадать на кофейной гуще тут никто не будет.
Смысл получать в скрипт 5000 наименований - отсутствует.
И обсуждать высосанные из пальца задачи никто не будет.
Это не выдвинул предположение, что при 5000 не будет разницы. Я всего лишь это (и не только это) проверил и написал о результатах проверки. Если не нравится, можете не обсуждать.
Автор оригинала: Фанат
Нужно воздержаться от таких комментариев.
Я бы посоветовал Вам и Wicked читать внимательнее топики и воздерживаться от своих комментариев не относящимся к теме топика. Если вам что-то не нравится, совсем не обязательно, что и другим это не понравится.


Автор оригинала: Фанат
неправда.
насколько я понимаю, тебе нужен селект из 100 пунктов вида
Австралия, Аделаида
Австралия, Перт
Австралия, Сидней
так?
это делается одним запросом. ПРОЩЕ.

ТАКИХ запросов больше нет.
все запросы РАЗНЫЕ
и делать надо в каждом случае ИНДИВИДУАЛЬНО.
Вид у него совсем другой. Я же написал что с группировкой по странам.
<OPTGROUP lable="Австралия">
<OPTION>Аделаида</OPTION>
<OPTION>Перт</OPTION>
</OPTGROUP>
Одним запросом придется проверять когда выводить <OPTGROUP lable="Австралия"> чтобы не вывести два раза.

-~{}~ 23.03.06 10:18:

А запросов таких как раз много если я написал то так оно и есть. Не стоит утверждать, что Вы знаете что мне нужно больше меня. Этот список выводится на многих страницах админки.
 

Фанат

oncle terrible
Команда форума
Я бы посоветовал Вам и Wicked читать внимательнее топики и воздерживаться от своих комментариев не относящимся к теме топика.
вот и воздержись.
второй раз предупреждать не буду.
Вид у него совсем другой.
всё равно одним запросом.

Ещё будут реальные вопросы?
 

magic

lancer
Я всего лишь это (и не только это) проверил и написал о результатах проверки. Если не нравится, можете не обсуждать.
Теркин, это не тесты, а куски кода, которые, как тебе кажется работают одинаково, хотя к тестам это не имеет никакого отношения.

Ответ тебе уже дали.
 
Сверху