Перейти до вмісту
Пошук в
  • Детальніше...
Шукати результати, які ...
Шукати результати в ...

Проблема с производительностью


Recommended Posts

Добрый день.

 

Столкнулся с долгой загрузкой страницы. Более минуты. Вывел лог запросов с MySql и увидел следующую картину - множество запросов вида:

SELECT count(DISTINCT p.product_id) AS total
FROM
  oc_product_to_category p2c
LEFT JOIN oc_product_filter pf
ON (p2c.product_id = pf.product_id)
LEFT JOIN oc_product p
ON (pf.product_id = p.product_id)
LEFT JOIN oc_product_description pd
ON (p.product_id = pd.product_id)
LEFT JOIN oc_product_to_store p2s
ON (p.product_id = p2s.product_id)
WHERE
  pd.language_id = '1'
  AND p.status = '1'
  AND p.date_available <= now()
  AND p2s.store_id = '0'
  AND p2c.category_id = '59'
  AND pf.filter_id IN (272)

Такой запрос выводит количество товаров в скобках по каждому фильтру.

Один такой запрос выполняется на моем сервере около 0,6 сек. Вроде немного. Но! Фильтров на странице 106 штук.

 

Почему нельзя было сделать все одним запросом?

SELECT pf.filter_id
     , count(DISTINCT p.product_id) AS total
FROM
  oc_product_to_category p2c
LEFT JOIN oc_product_filter pf
ON (p2c.product_id = pf.product_id)
LEFT JOIN oc_product p
ON (pf.product_id = p.product_id)
LEFT JOIN oc_product_description pd
ON (p.product_id = pd.product_id)
LEFT JOIN oc_product_to_store p2s
ON (p.product_id = p2s.product_id)
WHERE
  pd.language_id = '1'
  AND p.status = '1'
  AND p.date_available <= now()
  AND p2s.store_id = '0'
  AND p2c.category_id = '59'
  AND pf.filter_id IN (272,...много чисел..., 284)
GROUP BY
  pf.filter_id

А потом результирующую таблицу распарсить, десериализовать и т.д. до отдельного фильтра?

В итоге исходный вариант работает больше минуты. Мой вариант - 3.5 секунды.

 

И те же вопросы по остальным запросам. Все товары грузятся однотипными запросами. На странице 20 товаров - будет 20 запросов; 100 товаров - 100 запросов. Там меняется только id. Неужели за раз нельзя все выгребать?

 

P.S. В интернете нашел рекомендации по ускорению сайтов OpenCart. Там народ просто отключает в коде вычисление и отображение этих счетчиков на странице (количество товаров, количество категорий и т.д.). Вот это вообще как?

Змінено користувачем PaulMoriarty
Надіслати
Поділитися на інших сайтах


12 минут назад, PaulMoriarty сказал:

Столкнулся с долгой загрузкой страницы. Более минуты.

 

так устроены стандартные запросы в Opencart, и скорее всего, из коробки(дистрибутива) их не будут оптимизировать.

Надіслати
Поділитися на інших сайтах

4 hours ago, PaulMoriarty said:

Один такой запрос выполняется на моем сервере около 0,6 сек. Вроде немного.

Согласен. Но только если речь идет о какой-нибудь аналитике. Иной раз даже несколько минут - это очень быстро.

Но в вэбе это много даже для суммы всех запросов к базе, необходимых для генерации страницы.

4 hours ago, PaulMoriarty said:

Столкнулся с долгой загрузкой страницы. Более минуты.

А Вы терпеливый.

Сколько товаров в Вашем ИМ ?

Сколько максимум товаров внутри одной категории?

У Вас виртуальный (общий) хостинг или выделенный сервер?

 

4 hours ago, PaulMoriarty said:

Почему нельзя было сделать все одним запросом? 

Можно. Кусочек опенкартовской прелести в том, что переделать код под себя относительно просто.

Но, забегая вперед, Ваше решение едва ли более универсальное и более гибкое, как мне кажется: хуже подходит для кэширования; более длительные блокировки строк\таблиц базы при одном долгом селекте, потенциально, могут создавать неприятные последствия. Впрочем, конкретно у Вас оно может быть и лучше - просто имейте ввиду.

 

4 hours ago, PaulMoriarty said:

народ просто отключает в коде вычисление и отображение этих счетчиков на странице (количество товаров, количество категорий и т.д.). Вот это вообще как?

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

Надіслати
Поділитися на інших сайтах

Индексы там к таблицам добавить.
Вообще рекомендую фильтр от @vier.
Он годнотка.
Но, да, озвучьте конфигурацию хостинга и количество товара.
 

Надіслати
Поділитися на інших сайтах

1 час назад, splka сказал:

Индексы там к таблицам добавить.

не всегда много есть хорошо.

 

1 час назад, splka сказал:

Вообще рекомендую фильтр от @vier.
Он годнотка.

@splka у Вас еще 53 версия модуля, а уже 55. - в ней много новшеств, в том числе: в 54-й добавил конструирование собственного дизайна фильтра, а в 55-й добавлены возможность выводить атрибуты еще и select`ом и radio-кнопками.

#54

15_dizayn_osnovnoy_color.thumb.png.0ee0aed1bdc7fee0bad1eb11fc111f2d.png

 

#55

id_attrib_vibor.thumb.png.5f8c2965691138e86bbd3a3fce02d470.png

 

site_select_radio.thumb.png.b51486d59d12b69cdd860c00d22098c6.png

 

Надіслати
Поділитися на інших сайтах

Сразу хочу оговориться, с php и MySql я знаком очень-очень шапочно. Попросили посмотреть, что тормозит. Что-то переписывать и переделывать под себя я категорически не желаю.

Недоумение вызвал тот факт, что достаточно простенькая страница может грузиться так долго. Еще больше недоумения, когда выяснилось, что эта страничка делает несколько сотен запросов в БД. И окончательно добил факт, что тормозят эти счетчики еще с 1-ой версии OpenCart. Сейчас уже третья, а воз и ныне там.

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

 

Сервер свой, не хостинг. Конфиг: 2-ядерный Xeon 5160 @ 3 ГГц; RAM - 4 Гб; Windows Server 2008 R2, IIS 7.5; PHP 7.3.2; MySql 5.5.

Количество товаров, что-то около 67-68 тыс.

 

Но это все мелочи. Одна относительно средняя таблица соединяется с парой-тройкой мелких. Должно работать мгновенно.

На SqlServer я просто не задумываюсь о настройке подобных запросов. Написал похожий на мой, то что с группировкой, ради интереса. Таблица товаров далеко за 100.000 записей, категорий около 1000. Запрос выполнился за 20 мсек. Какие там могут быть долгие блокировки?

Змінено користувачем PaulMoriarty
Надіслати
Поділитися на інших сайтах


On 6/14/2019 at 4:23 PM, PaulMoriarty said:

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

Кому-то должны, кому-то нет... Нет жедания сводить все до кухонного разговора. Это не проблема в широком смысле слова. Есть как минимум несколько способов решить эту задачу. Как пруф - огромное количество ИМ на ОС с внущающим кол-ов товаров, которые не тормозят.

 

On 6/14/2019 at 4:23 PM, PaulMoriarty said:

Сразу хочу оговориться, с php и MySql я знаком очень-очень шапочно.

 

On 6/14/2019 at 4:23 PM, PaulMoriarty said:

Но это все мелочи. Одна относительно средняя таблица соединяется с парой-тройкой мелких. Должно работать мгновенно.

 

On 6/14/2019 at 4:23 PM, PaulMoriarty said:

На SqlServer я просто не задумываюсь о настройке подобных запросов

 

Верно. Должно работать очень быстро. Хотя бы потому, что джоин таблиц из запроса в стартовом посте происходит по первичным ключам. Убедитесь, для начала, что mysql в состоянии разместить все индексы баз данных в ОЗУ, а не производит их чтение с диска при выполнении запросов. Гуглите key_buffer_size, если Ваши таблички на myisam или innodb_buffer_pool_size, если имеют движок innodb. В первом случае все индексы всех myisam-таблиц БД должны помещаться в key_buffer_size; во втором, как вариант, можно можно установить значение = размеру всех данных и индексов в иннодб таблицах вместе взятых.

Надіслати
Поділитися на інших сайтах

Створіть аккаунт або увійдіть для коментування

Ви повинні бути користувачем, щоб залишити коментар

Створити обліковий запис

Зареєструйтеся для отримання облікового запису. Це просто!

Зареєструвати аккаунт

Вхід

Уже зареєстровані? Увійдіть тут.

Вхід зараз
  • Зараз на сторінці   0 користувачів

    • Ні користувачів, які переглядиють цю сторінку
×
×
  • Створити...

Important Information

На нашому сайті використовуються файли cookie і відбувається обробка деяких персональних даних користувачів, щоб поліпшити користувальницький інтерфейс. Щоб дізнатися для чого і які персональні дані ми обробляємо перейдіть за посиланням . Якщо Ви натиснете «Я даю згоду», це означає, що Ви розумієте і приймаєте всі умови, зазначені в цьому Повідомленні про конфіденційність.