powered by simpleCommunicator - 2.0.59     © 2025 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / MySQL [игнор отключен] [закрыт для гостей] / Оптимизация RAND()
24 сообщений из 24, страница 1 из 1
Оптимизация RAND()
    #39610243
Serg434
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Добрый день!
Знаю что тема уже заезжена, но не могу никак победить проблему в моих условиях и прошу помощи.

Есть задача вывести товар рандомно, но только из наличия.
И при добавлении rand(), запрос начинает выполнятся по 4-6 сек, что не есть хорошо.
Пока что это лучшее чего я смог добиться, но ОООЧЕНЬ долго.
Может кто сможет помочь?
Буду ОЧЕНЬ благодарен.

Вот код:
$q = '
select ci.id, ci.title, ci.cat_title, ci.brand_title, ci.brand_id, ci.cat_id, ci.modification, ci.desc_short, ci.price, ci.`exists`, cc.title_1 as cat_one from catalog_items ci, catalog_cats cc
where ci.cat_id in ('.implode(',',$cats_for_promo).')
and ci.cat_id=cc.id
order by `exists`, rand()
limit 4
';
...
Рейтинг: 0 / 0
Оптимизация RAND()
    #39612427
Фотография Amin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
выполните explain(код-вашего-запроса)

План выполнения сюда скиньте.
...
Рейтинг: 0 / 0
Оптимизация RAND()
    #39612447
Serg434
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Если я все правильно сделал, то вот результат.
Я, если честно, в этом не силен

1
SIMPLE
catalog_items
ALL
NULL
NULL
NULL
NULL
112264
100.00
Using temporary; Using filesort
...
Рейтинг: 0 / 0
Оптимизация RAND()
    #39612472
miksoft
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Serg434,

Опишите задачу более подробно - вывести куда и для чего?
Возможно, получится разнести во времени вывод и рандом.


Serg434order by `exists`Почему так, а не в секции WHERE?
...
Рейтинг: 0 / 0
Оптимизация RAND()
    #39612476
vkle
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Serg434И при добавлении rand(), запрос начинает выполнятся по 4-6 сек, что не есть хорошо.Угу. В таком варианте при выполнении запроса к каждой записи таблицы на лету добавляется дополнительное поле, для него вызывается функция rand() и только потом производится сортировка записей по значению поля. Потому долго уже при не очень большом количестве записей.

Как один из вариантов, добавить поле и заполнить его рандомными значениями заблаговременно. Конечно, алгоритм выборки 4-х строк придется изменить. Например, что-то вроде "больше значения NNN, которое задано один раз рандомным числом".
...
Рейтинг: 0 / 0
Оптимизация RAND()
    #39612488
miksoft
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
vkleКак один из вариантов, добавить поле и заполнить его рандомными значениями заблаговременно.Лучше непрерывно возрастающими целыми числами, т.е. перенумеровать. А потом "стрелять" в любой номер из диапазона 1..MAX_N
...
Рейтинг: 0 / 0
Оптимизация RAND()
    #39612502
vkle
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
miksoft,

Хороший вариант. Только стрелять 4 раза придется или формировать список из 4-х рандомных значений значений в IN. Фиг знает, что лучше. На большой таблице оно всяко лучше будет, чем WHERE `sort` > 123 ORDER BY `sort` LIMIT 4
...
Рейтинг: 0 / 0
Оптимизация RAND()
    #39612513
Serg434
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Расставлю все точки над и...
Я не спец, но люблю поковыряться в коде (познания общие).
Я владелец интернет магазина, на самописной CMS.
С разработчиками мы долго работали, но не сошлись характерами и тд...
Теперь я имею магазин, который работает, но его нужно допиливать по мелочи, чем я и решил заняться сам, т.к. нет возможности пока в него вкладываться.
Надеюсь я смогу найти здесь понимание и пинки в нужном направлении для самосовершенствования.

Запрос, который я хочу оптимизировать связан с выводом популярных товаров в определенной категории, скрин прилагается.

Изначально стояла ORDER BY popularity, но статистика почему то не собирается (с этим я буду разбираться потом), и в выдаче стояли постоянные товары, часть из которых уже даже снята с производства, потому я и решил что нужно показывать только товары из наличия и делать это рандомно, но запрос получается долгим.

А сделать это другим способом у меня мозга пока не хватает.

На сайте свыше 200 тыс карточек товаров

Если поможете буду крайне благодарен и надеюсь что не закидаете бананами)
...
Рейтинг: 0 / 0
Оптимизация RAND()
    #39612515
Serg434
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
И в след раз картинки буду под спойлер прятать
...
Рейтинг: 0 / 0
Оптимизация RAND()
    #39612538
miksoft
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Serg434Я владелец интернет магазина, на самописной CMS.Сочуствую... Много еще граблей разложено в тумане впереди...
Serg434Запрос, который я хочу оптимизировать связан с выводом популярных товаров в определенной категории, скрин прилагается.Как вариант, можно так:
1) Для товаров завести флаг "популярный товар".
2) В каждой категории произвести (и далее периодически проводить, например, раз в сутки или даже неделю) расчет флага так, чтобы в каждой категории было немного (например, 5% или 10 штук, по своему усмотрению) популярных товаров.
3) Выводить через WHERE category=123 AND popularity_flag=1 ORDER BY RAND() LIMIT 4
...
Рейтинг: 0 / 0
Оптимизация RAND()
    #39612541
miksoft
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Serg434И в след раз картинки буду под спойлер прятатьлучше вырезайте строго именно нужный фрагмент и сохраняйте в png, а не в jpg.
...
Рейтинг: 0 / 0
Оптимизация RAND()
    #39612600
Serg434
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
В таблице есть следующие столбцы:
id
internal_id
popularity
cat_id
article
brand_id
cat_title
cat_title_1
cat_title_instrumental
brand_title
title
modification
unit_id
price
price_lock
from_dealer_id
from_dealer_delivery
price_update_datetime
recommended_retail_price
exists
is_new
is_new_expires
is_hit
is_hit_expires
is_action
is_action_expires
desc_short
desc
meta_title
meta_keywords
meta_description
features_json

popularity у всех товаров 0.
и это значение не меняется.
поэтому даже и не знаю как собирать популярность.

Но идея в том, чтобы выдавать не популярные товары (для начала), а рандомные из наличия, тем самым увеличив ассортимент продаваемых товаров (если кто нибудь поиском не нашел)
...
Рейтинг: 0 / 0
Оптимизация RAND()
    #39612619
vkle
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Serg434Но идея в том, чтобы выдавать не популярные товары (для начала), а рандомные из наличия, тем самым увеличив ассортимент продаваемых товаров (если кто нибудь поиском не нашел)Может, ручками указывать для начала какие-то предлагаемые товары?
Будет статистика просмотров и покупок - можно её как-то дополнительно учесть. Но это ж сперва статистику делать надо.
...
Рейтинг: 0 / 0
Оптимизация RAND()
    #39612621
Serg434
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
vkleSerg434Но идея в том, чтобы выдавать не популярные товары (для начала), а рандомные из наличия, тем самым увеличив ассортимент продаваемых товаров (если кто нибудь поиском не нашел)Может, ручками указывать для начала какие-то предлагаемые товары?
Будет статистика просмотров и покупок - можно её как-то дополнительно учесть. Но это ж сперва статистику делать надо.
Ручками не вариант, потому что очень много товаров в разных категориях нужно отслеживать (наличие).
сайт работает уже 4 года, но статистика не собирается (с этим буду позже разбираться).
Для продвижения нужного товара вручную предусмотрен другой способ
...
Рейтинг: 0 / 0
Оптимизация RAND()
    #39612642
vkle
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ну раз ручками не вариант, тогда статистику просмотров или продаж делать. Товары с популярностью выше некоторой (возможно, индивидуально установленной для каждой категории товаров) и отсутствующие в наличии/продаже не выдавать в предложения вовсе, а из остального рандомная выборка. Как вариант, конечно.
...
Рейтинг: 0 / 0
Оптимизация RAND()
    #39612651
Serg434
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Посещаемость сайта пока не столь высока 100-150 уников в сутки.
Поэтому чтоб пока не заморачиваться с популярными товарами и тд... хотелось бы как то решить мой вопрос в быстрой обработке рандомных товаров из наличия
...
Рейтинг: 0 / 0
Оптимизация RAND()
    #39612659
vkle
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
А при нулевой популярности получается без разницы. Ноль будет всяко ниже предельной для показа планки. Хоть напишите эти условия, хоть не напишите - на результате оно не скажется никак.
Направлений для решения предложили уже по трем вариантам. Мой, скорее всего, будет чуть проще в реализации, но заведомо более тормозной, чем первый вариант, предложенный miksoft. Там два пути реализации - одним запросом или четырьмя в цикле. Обычно один запрос быстрее отрабатывает, но ,как говорится, бывают случаи.
Вариант, позже предложенный miksoft годится только для заранее явно назначенных к показу товаров. Назначить к показу можно ручками (не Ваш вариант), а можно сделать скрипт, который периодически случайным образом назначает новый список товаров. Если же назначить к показу все-все товары, получится, как раз ныне существующий медленный.
...
Рейтинг: 0 / 0
Оптимизация RAND()
    #39612662
Serg434
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
vkleЕсли же назначить к показу все-все товары, получится, как раз ныне существующий медленный.
Т.е. если я хочу выбрать из всех всех товаров, те, которые в наличии, как сейчас я сделал, это быстро! А если после этого выводить рандомно, то никак этот процесс не ускорить?
...
Рейтинг: 0 / 0
Оптимизация RAND()
    #39612676
vkle
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Serg434,

При таком подходе - никак. Если правильно понимаю внутреннюю кухню мускуля, там при выполнении запроса временная таблица с дополнительным полем создается как копия существующей (возможно, за вычетом фильтра отсутствующих товаров и т.п.), поле заполняется данными из функции, а после отработки запроса ставшая ненужной таблица удаляется.

Самая же быстрая выборка по индексированным числовым полям. Потому, если заранее пронумеруете записи то останется сгенерить несколько случайных чисел в заданном диапазоне (ага, как в Спортлото) и по ним выдернуть конкретные записи. Сложность в том, что при изменениях в таблице (товар добавился, ушел с продажи или вновь появился в продаже) придется так же перенумеровывать записи.

Ещё вариант. Подготовить потенциальные записи для показа заблаговременно (например, пара сотен записей) и держать их в отдельной таблице. Там можно и Ваш способ рандомной выборки использовать - на маленькой таблице работает приемлемо. Раз в час/сутки/неделю (по желанию) эту табличку обновлять, заменять список потенциальных для показа записей. Займет это десять секунд - но раз в сутки для отдельного скрипта на кроне - фигня, не заметно.
...
Рейтинг: 0 / 0
Оптимизация RAND()
    #39612944
Serg434
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
А будет ли смысл от следующих действий:?
1. Сделать выборку по наличию
2. Прописать им ID-шники от 1 до макс
3. Сделать рандомную выборку по ID?

Или это будет то же самое?
...
Рейтинг: 0 / 0
Оптимизация RAND()
    #39612946
vkle
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Serg434,

Давайте посмотрим, как это можно реализовать.

1 и 2 можно совместить, здесь в FAQ есть тема по нумерации строк. Другой вопрос, как много строк будет в выборке. Много строк - много времени уйдет. Вероятно, не так много, как в исходном варианте - счетчик работает быстрее чем rand(). Для однократного действия оно приемлемо, для формирования страницы сайта уже нет. Хранить эту выборку с пронумерованными строками придется в дополнительной таблице, скорее всего, ведь в п3 будут использованы номера строк.

Как вариант, дополнительную таблицу можно построить всего из двух полей - номер для выборки (автоинкрементное поле) и ID строки в основной таблице. Генерация таблицы связей быстрая получится, но при выборке потребуется JOIN и, как следствие, дополнительные ресурсы. Не интересно получается.

Этот вариант мне кажется менее интересен, чем использование дополнительного поля в основной таблице. От необходимости обновления при изменении наличия/доступности не избавляемся, а дополнительные сущности нарисовались.
...
Рейтинг: 0 / 0
Оптимизация RAND()
    #39612973
Serg434
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
vkle,

Ок.
Если я правильно понимаю, то в моем варианте, действие происходит так...
1. Выборка товаров из наличия
2. Рандомная сортировка этих товаров (самый долгий процес)
3. Выдача первых четырех строк.

Если это так, то можно ли сделать вместо 2 и 3 пунктов, просто 4 выстрела в первый вариант?
Или как раз для этого и потребуется нумерация строк?
Есть столбец с айдишниками, но они будут не попорядку
...
Рейтинг: 0 / 0
Оптимизация RAND()
    #39612985
Serg434
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
или я опять все перепутал?
...
Рейтинг: 0 / 0
Оптимизация RAND()
    #39613025
vkle
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Serg434Если это так, то можно ли сделать вместо 2 и 3 пунктов, просто 4 выстрела в первый вариант?
Или как раз для этого и потребуется нумерация строк?
Есть столбец с айдишниками, но они будут не попорядкуВсё верно. Айди не следует использовать для этой цели, они другую задачу решают.
Первый и последний номера строк фиксируете где-то (редко изменяемые значения) и используете для генератора случайных чисел. Четыре числа - четыре выстрела.
...
Рейтинг: 0 / 0
24 сообщений из 24, страница 1 из 1
Форумы / MySQL [игнор отключен] [закрыт для гостей] / Оптимизация RAND()
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]