Оптимизировать 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
.
ИИ поможет Вам:
- решить любую задачу по программированию
- объяснить код
- расставить комментарии в коде
- и т.д