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

ocStore тормозит при выключенном подсчете товаров


markimax

Recommended Posts

Нашел баг ocStore

ocStore тормозит при выключенном подсчете товаров, и большом количестве самих товаров, потому что все равно при заходе в категорию вызывается getTotalProducts (ну оочень сложный запрос работающий практически без индексов) для подкатегорий (а если их много ;), да даже одной хватает, чтобы "положить" сайт

 

И представьте перебор по 10`000 товаров  ;) ;(

 

Даже одного такого запроса хватает чтобы положить. сайт

 

Мало того если где либо используется модуль Акции или Последние (там есть вызов getProducts, а там то зачем считать количество ;) ) - всё, торба, тоже сайт будет "положен"

 

...потому что  в getProducts:

SELECT SQL_CALC_FOUND_ROWS.....

и далее сложный запрос.

 

Нельзя в getProducts использовать сразу подсчет количества.

 

Надо переделывать, что модель catalog/product.php что контроллер product/category.php

 

3429590847.jpg

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

В категориях считается кол-во товара для формирования пагинации или есть другие варианты?

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


я так понимаю ты предлагаешь это количество не подсчитывать?

Да, в подкатегориях то зачем считать, если выключен подсчет категорий?

Представь тот сложный запрос на 10`000 товаров - я проверял - ложит сайт сразу

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

В категориях считается кол-во товара для формирования пагинации или есть другие варианты?

Там не только в категориях считает, но считает и подсчет в подкатегориях

 

196 строка product/category.php

            foreach ($results as $result) {
                $data = array(
                    'filter_category_id'  => $result['category_id'],
                    'filter_sub_category' => true
                );
                
                $product_total = $this->model_catalog_product->getTotalProducts($data);       

Зачем? Если выключен подсчет

 

А для пагинации идет код следом

$this->data['products'] = array();
            
            $data = array(
                'filter_category_id' => $category_id,
                'filter_filter'      => $filter,
                'sort'               => $sort,
                'order'              => $order,
                'start'              => ($page - 1) * $limit,
                'limit'              => $limit
            );
                    
            $results = $this->model_catalog_product->getProducts($data);
            //Вызов метода getFoundProducts должен проводится сразу же после getProducts
            //только тогда он выдает правильное значения количества товаров
            $product_total = $this->model_catalog_product->getFoundProducts();
Надіслати
Поділитися на інших сайтах

getTotalProducts
хм...
Ну... можно чуть чуть упростить запрос...
Скажем, на первом этапе

		$sql = "SELECT COUNT(DISTINCT p.product_id) AS total"; 

/* пропущенна часть фильтров */		
		
		$sql .= " LEFT JOIN " . DB_PREFIX . "product_description pd ON (p.product_id = pd.product_id) LEFT JOIN " . DB_PREFIX . "product_to_store p2s ON (p.product_id = p2s.product_id) WHERE pd.language_id = '" . (int)$this->config->get('config_language_id') . "' AND p.status = '1' AND p.date_available <= '" . $this->NOW . "' AND p2s.store_id = '" . (int)$this->config->get('config_store_id') . "'";


 
Так вот здесь можно не подключать  product_description если сайт одноязычный.

 

Подразумевается, что для некоторых языков может не быть товара.

 

Но для фильтра или например, поиска, не забудьте подключить!!!

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

getTotalProducts

Так вот здесь можно не подключать  product_description если сайт одноязычный.

 

Подразумевается, что для некоторых языков может не быть товара.

 

Но для фильтра или например, поиска, не забудьте подключить!!!

Не выход запрос все равно будет перебирать всю таблицу товаров (ну вот такой он сложный), а представьте их там порядка 10`000 - ...

:cry:

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

Стоп... а каком запросе речь идет?

 

Я говорю о

    public function getTotalProducts($data = array()) {

в /model/catalog/product

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

О каком запросе идет речь?

 

Может у нас разные запросы?

Из модели catalog/product public function getTotalProducts

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

explain 

SELECT COUNT(DISTINCT p.product_id) AS total FROM t_product p

LEFT JOIN t_product_to_store p2s ON (p.product_id = p2s.product_id)

WHERE p.status = '1' AND p.date_available <= NOW() AND p2s.store_id = '0'

id  select_type table  type    possible_keys  key      key_len  ref             rows   Extra

1   SIMPLE      p2s    index   PRIMARY        PRIMARY  8        NULL            181    Using where; Using index

1   SIMPLE      p      eq_ref  PRIMARY        PRIMARY  4        p2s.product_id  1      Using where

define('VERSION', '1.5.5.1.1');
Надіслати
Поділитися на інших сайтах

explain 
SELECT COUNT(DISTINCT p.product_id) AS total FROM t_product p 
LEFT JOIN t_product_to_store p2s ON (p.product_id = p2s.product_id) 
WHERE p.status = '1' AND p.date_available <= NOW() AND p2s.store_id = '0'
id  select_type table  type    possible_keys  key      key_len  ref             rows   Extra
1   SIMPLE      p2s    index   PRIMARY        PRIMARY  8        NULL            181    Using where; Using index
1   SIMPLE      p      eq_ref  PRIMARY        PRIMARY  4        p2s.product_id  1      Using where

Это сколько товаров в БД и в этой категории?

rows - Количество рядов, которые MySQL необходимо проверить, для обработки запроса.

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

Как видите - товаров всего 181

Ведь никаких фильтров.

Но это сути то не меняет.

Да подсчет количества - это всегда г...е дело. Количество надо кешировать или как делают по другому - делают окно, например Limit

и типа пагинация 1 2 3.....

если много товаров или 1 2 если 2 страницы влезло в окно, некоторые просто делают кнопку дальше а окно делают на 2 страницы

Тогда всё очень быстро летает на нагруженных проектах.

Посмотрите как у youtube например

https://www.youtube.com/results?search_query=%D0%BC%D1%83%D0%B7%D1%8B%D0%BA%D0%B0&sm=3

 

Там "окно" - 7 страниц, т.е. если в пагинации убрать "последнюю" то запросто можно использовать окно в пагинации если не использовать подсчет количества в категориях то на нагруженных проектах всё будет летать

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

Соглашусь. Можно подсчитывать до определённого количества, а  дальнейший подсчёт вызывать например при помощи аякс. Единственный минус,что человек не видит сразу сколько товара в категории, но на тяжёлых проектах это спасёт.

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


Ну... ведь никто вам не мешает сделать также...

редкая птица долетит до середины Днепра

Я имею ввиду при большом количестве товара будет ходить по пагинации перескакивая десятки страниц.

 

Конечно, можно и кешировать, но что кешировать?

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

Соглашусь. Можно подсчитывать до определённого количества, а  дальнейший подсчёт вызывать например при помощи аякс. Единственный минус,что человек не видит сразу сколько товара в категории, но на тяжёлых проектах это спасёт.

Да,  надо сделать в ocStore - что-то типа настройки пагинации для нагруженных проектов  там всего-то LIMIT в запрос добавить на определенное окно, т.е. если количество выводимых товаров 20 и окно на 5 страниц, то LIMIT 100, тогда при 30 товаров все будет ОК - покажет только нужное количество страниц - 2, а если больше то  1 2 3 4 5 ...

Надо только шаблон пагинации подправить

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

Ну... ведь никто вам не мешает сделать также...

редкая птица долетит до середины Днепра

Я имею ввиду при большом количестве товара будет ходить по пагинации перескакивая десятки страниц.

 

Конечно, можно и кешировать, но что кешировать?

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

 

Вообще система кеширования OC очень слабенькая

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

Ну... Что кешировать

 

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

 

Частичная пагинация - частный случай.

Оптимальный выход - делать аякс пагинацию, с кнопкой "посмотреть еще". Опять же частный случай.

 

Или как г-н Гугл.. нарисовать кнопки пагинации , а потом сказать... мы скрыли от вас похожие результаты.

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

Или как г-н Гугл.. нарисовать кнопки пагинации , а потом сказать... мы скрыли от вас похожие результаты.

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

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

А если создать доп таблицу, в которой и хранить все счётчики?

Во-первых это несколько отдаляет от чистого OC.

Во-вторых, как будет наполнять таблица? Например, в случае наполнения базы модулем импорта ...?

Как по мне, кеширование - самое оно.

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


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

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

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

 

Вообще система кеширования OC очень слабенькая

Так время жизни лечится парой строчек. Я у себя давно метод set из класса кеша переписал

      private $expire = 3600;

      public function set($key, $value, $expire=false) {
        $this->delete($key);
        if (!$expire) $expire=$this->expire;
        $file = DIR_CACHE . 'cache.' . preg_replace('/[^A-Z0-9\._-]/i', '', $key) . '.' . (time() + $expire);
        $handle = fopen($file, 'w');
        fwrite($handle, serialize($value));
        fclose($handle);
      }
Надіслати
Поділитися на інших сайтах


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

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

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

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

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

Вхід

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

Вхід зараз

×
×
  • Створити...

Important Information

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