Mysql Оптимизировать запрос, в таблице 6млн записей

antson

Новичок
Партнер клуба
если сервак боевой. экспериментировать не рекомендую. Подключай админа и/или DBA
 

Yoskaldyr

"Спамер"
Партнер клуба
как решить проблему с order, можете подсказать?
Какое время запроса без сортировки?

И чтобы помочь надо понимать бизнес задачи, т.е. что должно в итоге получится. Если пытаться оптимизировать неправильный запрос который делает бесполезную работу, то в итоге все равно будет запрос, который все так же делает бесполезную и бессмысленную работу .

И поддерживаю насчет того что нужен или дба или сисадмин. Без понимания того что делаешь можно бесповоротно убить базу.
 

lolka02

Новичок
@Yoskaldyr, ну пока нас интересует только этот запрос, в основном в логах самый долговыполняющий этот пока, а переписывать времени нет)
 

fixxxer

К.О.
Партнер клуба
product_id лишнее уберу его, или что еще? без дистинкта не получилось сделать запрос, иначе появлялись дубли
Ну так дубли же не просто так. Значит, наджойнилось. Значит, где-то надо либо уточнять условия джойнов, либо правильно делать группировку. Подозреваю, что результаты запроса в итоге вообще некорректны: mysql до версии 5.7.5 по умолчанию в таком случае берет в рамках группы первую попавшуюся строку, а остальные откидывает. Начиная с 5.7.5 будет ошибка.

Советую сделать вот так:
SET SESSION sql_mode = 'ANSI,ONLY_FULL_GROUP_BY';

и переписать запрос так, чтобы не было ошибки 1055. Заодно, может, и проблемы с производительностью решатся. :)
 

lolka02

Новичок
@fixxxer, дубли появляются из за того, что я делаю выборку через product_to_tag а там у одного товара может быть сколько тегов.
 

fixxxer

К.О.
Партнер клуба
А, вижу.
На современной версии mysql имело бы смысл попробовать подзапросы на product_to_tag (хотя зависит от селективности).
С такой древостью - остается страдать.
 

fixxxer

К.О.
Партнер клуба
Если продуктов после фильтрации по тэгам остается немного, можно попробовать что-то вроде
PHP:
select product.*, company.*, ...
from product,
...,
(
    select distinct product_id from product_to_tag
    where product_to_tag.tag_id in (...)
) filter
where filter.product_id = product.id
...
но, опять же, с таким древним mysql...
 

Redjik

Джедай-мастер
не думаю что в любой базе такое получится сделать с хорошим временем
группировка и сортировка - 100% temp table создадут
в принципе не критично, можно и в памяти довольно шустро гонять, но цпу вырастет, если запросов много
ну и как @fixxxer сказал
Если продуктов после фильтрации по тэгам остается немного
если много, то надо другой вариант искать

я бы подумал в сторону стратегии посчитать похожие продукты заранее с пересчетом по крону (в таблицу связку)
на PG подобную фигню разрулили через materialized view и refresh concurrently каждые 5 минут
¯\_(ツ)_/¯
 

lolka02

Новичок
насчет индексов стоит ли удалить индекс time_publish (publish, timestamp_update) ?
 

Redjik

Джедай-мастер
угу, но вообще как я понял проблема в том, что есть товары в корзине, а нужно показать похожие на эти товары
из-за этого то и появляются дубли и нужна группировка

можно еще поиграться с подзапросами, как опять же написал @fixxxer
такое в постгресе точно очень хорошо работает =))))
 

antson

Новичок
Партнер клуба
попробовать вытаскивать похожие товары для каждого товара . от 1 до 5-ти (наверное будет, не знаю какой у вас средний чек )

ошибся по каждому тегу ;(
в сумме время более простых запросов может оказаться лучше одного сложного.

измени вот эту часть
AND (product.id != 5016460) AND (c.id = 99 or c.parent_id = 99)

c.id = 99 or c.parent_id = 99
ввести в базу еще одно
поле region ? если правильно понимаю , что нам даст более быстрое условие
c.region = 99

product.id != 5016460 - выкинуть из запроса
можно пробежать по результату и сделать unset
 
Последнее редактирование:

lolka02

Новичок
@Yoskaldyr, насчет переписывания сайта, все равно же такие моменты (связи)надо будет сделать через нормализацию или есть другой вариант?
 

antson

Новичок
Партнер клуба
@lolka02,
ORDER BY `product`.`timestamp_update` limit 30
бесполезная часть.

как понимаю company_id - тут у тебя аля tui ali avito, т.е. очередной маркет товаров для компаний.
и выводить желательно
а) по одному подходящему товару от компаний .
б) проплаченных вперед
в) обновляющих цены регулярно
г) досыпать до кол-ва с ротацией
 
Сверху