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

Есть задача вывести товар рандомно, но только из наличия.
И при добавлении 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
09.03.2018, 08:43
    #39612427
Amin
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Оптимизация RAND()
выполните explain(код-вашего-запроса)

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

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

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


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

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

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

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

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

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

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

Если поможете буду крайне благодарен и надеюсь что не закидаете бананами)
...
Рейтинг: 0 / 0
09.03.2018, 12:44
    #39612515
Serg434
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Оптимизация RAND()
И в след раз картинки буду под спойлер прятать
...
Рейтинг: 0 / 0
09.03.2018, 13:43
    #39612538
miksoft
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Оптимизация RAND()
Serg434Я владелец интернет магазина, на самописной CMS.Сочуствую... Много еще граблей разложено в тумане впереди...
Serg434Запрос, который я хочу оптимизировать связан с выводом популярных товаров в определенной категории, скрин прилагается.Как вариант, можно так:
1) Для товаров завести флаг "популярный товар".
2) В каждой категории произвести (и далее периодически проводить, например, раз в сутки или даже неделю) расчет флага так, чтобы в каждой категории было немного (например, 5% или 10 штук, по своему усмотрению) популярных товаров.
3) Выводить через WHERE category=123 AND popularity_flag=1 ORDER BY RAND() LIMIT 4
...
Рейтинг: 0 / 0
09.03.2018, 13:45
    #39612541
miksoft
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Оптимизация RAND()
Serg434И в след раз картинки буду под спойлер прятатьлучше вырезайте строго именно нужный фрагмент и сохраняйте в png, а не в jpg.
...
Рейтинг: 0 / 0
09.03.2018, 16:20
    #39612600
Serg434
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Оптимизация RAND()
В таблице есть следующие столбцы:
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
09.03.2018, 16:43
    #39612619
vkle
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Оптимизация RAND()
Serg434Но идея в том, чтобы выдавать не популярные товары (для начала), а рандомные из наличия, тем самым увеличив ассортимент продаваемых товаров (если кто нибудь поиском не нашел)Может, ручками указывать для начала какие-то предлагаемые товары?
Будет статистика просмотров и покупок - можно её как-то дополнительно учесть. Но это ж сперва статистику делать надо.
...
Рейтинг: 0 / 0
09.03.2018, 16:49
    #39612621
Serg434
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Оптимизация RAND()
vkleSerg434Но идея в том, чтобы выдавать не популярные товары (для начала), а рандомные из наличия, тем самым увеличив ассортимент продаваемых товаров (если кто нибудь поиском не нашел)Может, ручками указывать для начала какие-то предлагаемые товары?
Будет статистика просмотров и покупок - можно её как-то дополнительно учесть. Но это ж сперва статистику делать надо.
Ручками не вариант, потому что очень много товаров в разных категориях нужно отслеживать (наличие).
сайт работает уже 4 года, но статистика не собирается (с этим буду позже разбираться).
Для продвижения нужного товара вручную предусмотрен другой способ
...
Рейтинг: 0 / 0
09.03.2018, 17:49
    #39612642
vkle
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Оптимизация RAND()
Ну раз ручками не вариант, тогда статистику просмотров или продаж делать. Товары с популярностью выше некоторой (возможно, индивидуально установленной для каждой категории товаров) и отсутствующие в наличии/продаже не выдавать в предложения вовсе, а из остального рандомная выборка. Как вариант, конечно.
...
Рейтинг: 0 / 0
09.03.2018, 18:04
    #39612651
Serg434
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Оптимизация RAND()
Посещаемость сайта пока не столь высока 100-150 уников в сутки.
Поэтому чтоб пока не заморачиваться с популярными товарами и тд... хотелось бы как то решить мой вопрос в быстрой обработке рандомных товаров из наличия
...
Рейтинг: 0 / 0
09.03.2018, 18:41
    #39612659
vkle
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Оптимизация RAND()
А при нулевой популярности получается без разницы. Ноль будет всяко ниже предельной для показа планки. Хоть напишите эти условия, хоть не напишите - на результате оно не скажется никак.
Направлений для решения предложили уже по трем вариантам. Мой, скорее всего, будет чуть проще в реализации, но заведомо более тормозной, чем первый вариант, предложенный miksoft. Там два пути реализации - одним запросом или четырьмя в цикле. Обычно один запрос быстрее отрабатывает, но ,как говорится, бывают случаи.
Вариант, позже предложенный miksoft годится только для заранее явно назначенных к показу товаров. Назначить к показу можно ручками (не Ваш вариант), а можно сделать скрипт, который периодически случайным образом назначает новый список товаров. Если же назначить к показу все-все товары, получится, как раз ныне существующий медленный.
...
Рейтинг: 0 / 0
09.03.2018, 18:53
    #39612662
Serg434
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Оптимизация RAND()
vkleЕсли же назначить к показу все-все товары, получится, как раз ныне существующий медленный.
Т.е. если я хочу выбрать из всех всех товаров, те, которые в наличии, как сейчас я сделал, это быстро! А если после этого выводить рандомно, то никак этот процесс не ускорить?
...
Рейтинг: 0 / 0
09.03.2018, 20:28
    #39612676
vkle
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Оптимизация RAND()
Serg434,

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

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

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

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

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

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

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

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

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

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


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