Исходная ситуация
- сайт на Drupal 5 (www.biser.info),
- 3 500 посещения / день
- 2 000 000 просмотров / месяц
- 16 000 нодов, из них 95 % это картинки, добавленные через модуль Image
- в среднем 50 обращений к БД в секунду
Установив модуль Devel обнаружил, что одно из обращений к БД, сжирает 40% всего времени.
Это запрос в функции image_get_random().
function image_get_random($count = 1, $tid = 0) {
if ($tid != 0) {
$result = db_query_range(db_rewrite_sql("SELECT n.nid FROM {term_node} tn LEFT JOIN {node} n ON n.nid=tn.nid WHERE n.type='image' AND n.status=1 AND tn.tid=%d ORDER BY RAND()"), $tid, 0, $count);
}
else {
$result = db_query_range(db_rewrite_sql("SELECT n.nid FROM {node} n WHERE n.type='image' AND n.status=1 ORDER BY RAND()"), 0, $count);
}
$output = array();
while ($nid = db_fetch_object($result)) {
$output[] = node_load(array('nid' => $nid->nid));
}
return $output;
}
?>
Этот запрос выдаёт id нода для отображения в блоке Случайное фото.
Добавив несколько изменений удалось сократить время в ~70 раз.
Изменённая функция
function image_get_random($count = 1, $tid = 0) {
$max_node_id = db_result(db_query("SELECT id FROM {sequences} WHERE name = '%s'", 'node_nid'))-50;
$rand_node_id = rand(1,$max_node_id);
if ($tid != 0) {
$result = db_query_range(db_rewrite_sql("SELECT n.nid FROM {term_node} tn LEFT JOIN {node} n ON n.nid=tn.nid WHERE n.type='image' AND n.status=1 AND tn.tid=%d ORDER BY RAND()"), $tid, 0, $count);
}
else {
$result = db_query_range(db_rewrite_sql("SELECT n.nid FROM {node} n WHERE n.type='image' AND n.status=1 AND nid >= $rand_node_id "), 0, $count);
}
$output = array();
while ($nid = db_fetch_object($result)) {
$output[] = node_load(array('nid' => $nid->nid));
}
return $output;
}
?>
Может кому-нибудь это тоже поможет.
Комментарии
Интересно а подводных камней тут нет!? и самое главное чтоб не всплыли не вовремя!
Спасибо!
Не должно быть подводных камней.
Раньше rand() делала MySQL а теперь PHP.
В 70 раз уменьшилось время запроса, но насколько возвросло время исполнения PHP-функции? Тестировалось, быстрее ли rand в PHP?
странные какиеты SQL запросы.
что значит "ORDER BY RAND()" ?
ORDER BY вообщето упорядочивает по какому-то полю таблицы, в данном случае всего 2 поля. Какой в этом смысл?? Помоему проще будет извлечь нужные айдишники и потом уже их рэндомно выкидывать через php.
RTFM
http://dev.mysql.com/doc/refman/5.0/en/mathematical-functions.html#funct...
Установив модуль Devel обнаружил, что одно из обращений к БД, сжирает 40% всего времени.
Не всего времени, а времени работы именно с БД.
Не всего времени, а времени работы именно с БД.
спасибо, я просто не корректно выразился
попробуйте вот так
http://forums.mysql.com/read.php?24,163940,163944#msg-163944
погуглил, оказывается действительно RAND() тормозит на больших таблицах
а может того, разрабам отправить?
На 2bits.com появилась стоящая внимания статья How to create a block with images in rotation о том как создать блок в котором будут отображаться случайные картинки. Данный блок не использует базу данных, берет картинки прямо из указанной директории.
Извините за глупый вопрос, но почему бы не вставлять картинки по средствам html-кода?
потгмушта пасрецтвам хтмлкода случайныи картинки не получаютса
Извините за второй глупый вопрос:) но меня всегда смущали блоки «случайные картинки, статьи и т.д.»
Человек приходит на сайт за какой-то конкретной информацией, а ему показывают «случайные картинки»!? Спрашивается «НАФИГА!». Если человеку нужно что-то случайное, он бы не заходил на этот конкретный сайт!
Ну и в сторону позитивного вывода:
«Карфаген должен быть разрушен»Гораздо полезнее блок «Похожие материалы»П.С. В нашем модуле картинок, который мы все не можем доделать, случайных картинок не будет.
П.П.С. Я знаю - город будет, я знаю – саду цвесть! (к июню мы выложим свой фото-модуль)
Около года назад я убрал этот блок так пользователи меня чуть не съели. Вернул на второй день
Ну случайному человеку может и не нужен. А для регулярного посетителя - почему бы и нет. В магазине каком-нить - фото какого попало товара (вдруг понравится), на сайте местного сообщества - просто фото из альбома, шоб не скучно было