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