Оптимизировать mysql запрос

123 4
BasePelleta
На сайте с 29.05.2008
Offline
120
1936

Есть такой блок, который выводит рандомно релевантные статьи из категории.

Данные кэшируются, но при рандомной выборке (rand() AS rnd)

при выводе статьи блок релевантных статей постонянно меняется.

1. Хотелось бы сделать так, чтобы при обновлении страницы новый рандомный

запрос выполнялся через некоторый интервал.

2. Где-то читал, что конструкция (rand() AS rnd) в запросе к мускулу не производительна

и может быть причиной slow queries. Ее можно как-то оптимизировать, усовершенствовать?

function Random_Related_Articles(&$tpl){


global $db,$a_Ad,$TITLE_FIELD;
/*
$ql = 'SELECT link_id AS o_id,'.$TITLE_FIELD.' AS o_title, images AS o_images, b_descr AS o_descr, rand() AS rnd FROM '.TBL_AD.
' WHERE catid="'.$a_Ad['catid'].'"'.
FilterGetSQL().' GROUP BY '.$TITLE_FIELD.' ORDER BY rnd LIMIT 3';
*/

################ REGION CRITERION ###########

$reg_id = REGION_CRITERION;

#############################################

#AND _region_id IN (".get_daughter_cats($reg_id, ModTable('Regions','category'))

$ql = 'SELECT link_id AS o_id,'.$TITLE_FIELD.' AS o_title, images AS o_images, b_descr AS o_descr, rand() AS rnd FROM '.TBL_AD.
' WHERE catid="'.$a_Ad['catid'].'"AND _region_id IN ('.get_daughter_cats($reg_id, ModTable('Regions','category')).')
'.FilterGetSQL().' GROUP BY link_id ORDER BY rnd LIMIT 4';


$res = $db->query($ql);

while($v = mysql_fetch_assoc($res)){

if($v['o_images']) list($v['o_images']) = explode("\n",$v['o_images']);

$title_url = SearchFriendlyURL($v['o_title']);

$v['o_ad_url'] = $title_url.'-o'.$v['o_id'].'.html';

#var_dump ($v['o_ad_url']);

$v['o_descr'] = strip_tags($v['o_descr']);

$v['o_descr'] = Cut_Text_by_words($v['o_descr'], 100);
$v['o_alt'] = Cut_Text_by_words($v['o_title'], 25);

$tpl->AddCell('b_Random_Related_Articles',$v);
}

}
LEOnidUKG
На сайте с 25.11.2006
Offline
1723
#1

Считывайте все ID из таблицы, потом через PHP выбирайте рандомом из этого массива 1 значения и делайте уже запрос с точным ID и LIMIT 1

✅ Мой Телеграм канал по SEO, оптимизации сайтов и серверов: https://t.me/leonidukgLIVE ✅ Качественное и рабочее размещение SEO статей СНГ и Бурж: https://getmanylinks.ru/
BasePelleta
На сайте с 29.05.2008
Offline
120
#2
Считывайте все ID из таблицы, потом через PHP выбирайте рандомом из этого массива 1 значения и делайте уже запрос с точным ID и LIMIT 1

А если мне нужно от 3-10 значений в зависимости от настроек?

LEOnidUKG
На сайте с 25.11.2006
Offline
1723
#3
BasePelleta:
А если мне нужно от 3-10 значений в зависимости от настроек?

for или while Вам в помощь, пусть в цикле формируются и закидываются в $randin[]

Потом просто 1 запрос с указанием какие ID вывести.

Joker-jar
На сайте с 26.08.2010
Offline
154
#4

1. Читать этот блок из текстового файла. Текстовый файл обновлять кроном (либо то же самое сделать непосредственно на PHP. Если таймаут прошел, вытаскиваем из БД, заносим в файл, отображаем, иначе отображаем из файла)

2.

А если мне нужно от 3-10 значений в зависимости от настроек?

Разницы нет. Выбирайте сколько нужно, потом select ... from ... where id in (...)

P.S. Если записей очень много, то, думаю, на счет второго пункта надо еще помозговать

LEOnidUKG
На сайте с 25.11.2006
Offline
1723
#5

хотя можно даже без цикла...

Просто берёте все ID в массив, перемешиваете и берёте первых 3-10 элемента.

:)

Joker-jar
На сайте с 26.08.2010
Offline
154
#6

Как вариант, если, допустим статей в базе очень много, а выбрать надо всего 3-5 случайных, то рациональнее выполнить N запросов вида

SELECT ... FROM ... WHERE ID <= rand LIMIT 1

где rand - число в диапазоне 0..кол-во_статей, сгенерированное пхп

AlexVenga
На сайте с 10.04.2007
Offline
190
#7

выбирайте ID в массив и рандомьте его - array_rand($array,сколько новостей надо)

так проще и ненадо при выборе случайной новости проверять нет ли её уже

AlexVenga добавил 24.08.2011 в 15:41

блин, пока писал опередили....

AlexVenga добавил 24.08.2011 в 15:43

Joker-jar:
Как вариант, если, допустим статей в базе очень много, а выбрать надо всего 3-5 случайных, то рациональнее выполнить N запросов вида
SELECT ... FROM ... WHERE ID <= rand LIMIT 1

где rand - число в диапазоне 0..кол-во_статей, сгенерированное пхп

тут ещё надо смотреть чтобы новости не повторялись... неудобно....

Антикризисное предложение: [Бурж, AdSense] [NEW] Сайты - каталоги компаний с гарантией трафа [Дорого] (/ru/forum/1006462)
BasePelleta
На сайте с 29.05.2008
Offline
120
#8
Читать этот блок из текстового файла. Текстовый файл обновлять кроном (либо то же самое сделать непосредственно на PHP. Если таймаут прошел, вытаскиваем из БД, заносим в файл, отображаем, иначе отображаем из файла)

Вариант такой имеется и он работает для одной страницы с новостью, а если страниц больше 1, то бля каждой создавать текстовый файл ?

AlexVenga
На сайте с 10.04.2007
Offline
190
#9

у меня таких файлов 85к и обновляютя раз в сутки, но не по крону а по дате обновления файла чтобы не все сразу - работает прекрасно

Joker-jar
На сайте с 26.08.2010
Offline
154
#10

Один блок = один файл. А на скольких страницах этот блок не важно. Либо я вас не до конца понял.

123 4

Авторизуйтесь или зарегистрируйтесь, чтобы оставить комментарий