Оптимизировать SQL запрос с выбором рандомных строк - MySQL
Формулировка задачи:
Доброго времени суток.
Уже всю голову сломал. Интернет магазин. Штук 100 категорий, в каждой категории есть товары.
Требуется вывести в рекламный баннер десять рандомных товаров из БД.
ВАЖНО: id товаров не идут по порядку в БД, то есть выбрать нужно только определенные.
Вот как делаю я:
Помогите оптимизировать этот код. если на каждую страницу по 2 сек и добавить еще сотни пользователей на сайт. Нагрузка на сервере возрастает с 6% до 50%. Хостер матерится.
Очень прошу помощи
$time1 = microtime(true)*1 ; // засекаю время начала скрипта
$query02 = 'SELECT `sp_items`.`id_items`
FROM `sp_items`, `sp_purchases` , `sp_cats`
WHERE `sp_items`.`purchase_id` =`sp_purchases`.`id_purchases`
AND `sp_purchases`.`state`=0
AND `sp_items`.`catalog_id`=`sp_cats`.`id_cats`
AND `sp_cats`.`deletecat` = 0
And `sp_items`.`price` > 0
AND `sp_items`.`hidden` = 0
AND `sp_items`.`invisible` = 0
And `sp_items`.`image_urls` <> "a:0:{}"';
$res02 = $db->sql_query($query02); // делаю запрос к БД
$num2 = $res02->num_rows; // число строк
echo $num2.'<br>'; // этот код просто для информации. ИТОГ 186000 строк
$time2 = microtime(true)*1 ;
$time=($time2-$time1);
echo $time.'<br>'; // время исполнения до 2.5-3 секунд
while($row = $db->sql_fetchrow($res02)) // раскладываю получившийся результат на строки
{
$ava_ids02[] = $row['id_items']; // получаю массив с результатами
}
$massiv=array(); // объявляю новый массив в котором будут выбранные id для баннера
while (count($massiv) < 10) {
$rnd=rand(0, ($num2 - 1));
$massiv[] = $ava_ids02[$rnd]; // получаю массив из 10 рандомных id товаров
}
//далее уже делаю конкретный запрос с данными товаров по их id, находящимся в созданном массиве $massiv
$query = "SELECT id_items, purchase_id, catalog_id, name, price, image_urls FROM sp_items WHERE id_items IN (".implode(',',$massiv).") ORDER BY id_items desc LIMIT ".count($massiv);Решение задачи: «Оптимизировать SQL запрос с выбором рандомных строк»
textual
Листинг программы
$query02 = 'EXPLAIN SELECT `sp_items`.`id_items`
FROM `sp_items`, `sp_purchases` , `sp_cats`
WHERE `sp_items`.`purchase_id` =`sp_purchases`.`id_purchases`
AND `sp_purchases`.`state`=0
AND `sp_items`.`catalog_id`=`sp_cats`.`id_cats`
AND `sp_cats`.`deletecat` = 0
And `sp_items`.`price` > 0
AND `sp_items`.`hidden` = 0
AND `sp_items`.`invisible` = 0
And `sp_items`.`image_urls` <> "a:0:{}"';
$res02 = $db->sql_query($query02);
$num2 = $res02->num_rows; // число строк
echo $num2.'<br>';
$time2 = microtime(TRUE)*1 ;
$time=($time2-$time1);
echo $time.'<br>';
while($row = $db->sql_fetchrow($res02))
{
$ava_ids02[] = $row['id_items'];
}
$sss=COUNT($ava_ids02);
while (COUNT($massiv) < 10) {
$rnd=rand(0, ($sss - 1));
$massiv[] = $ava_ids02[$rnd];
}
print_r($massiv);
Объяснение кода листинга программы
- Создается переменная
$query02, которая содержит SQL-запрос. - SQL-запрос выбирает случайные строки из таблицы
sp_items, которые удовлетворяют определенным условиям. - Выполняется SQL-запрос с помощью метода
sql_queryобъекта$db. - Результат запроса сохраняется в переменной
$res02. - Определяется количество строк в результате запроса с помощью метода
num_rowsобъекта$res02. - Вычисляется время выполнения запроса с помощью функции
microtime. - В цикле
whileпроходят все строки результата запроса и сохраняют значения столбцаid_itemsв массив$ava_ids02. - Определяется количество элементов в массиве
$ava_ids02. - В цикле
whileслучайным образом выбираются элементы из массива$ava_ids02и добавляются в другой массив$massiv. - Массив
$massivвыводится с помощью функцииprint_r.