Перейти к содержанию

Рекомендуемые сообщения

Недавно обратился клиент (OcStore 1.5.5.1.2.) с просьбой посмотреть и узнать где именно тормоза на сайте. Так как, на сайте под завязку используются опции и аттрибуты, я стал грешить на них еще до проверки, проверка xhprof дала понять, что я не ошибался. Одним кэшированием тут не отделаться, так как данные магазина постоянно обновляются и механизм инвалидации кэша далек от идеала.

 

Было принято решение оптимизировать функции получения списка аттрибутов и опций. Что именно сделано: Убраны дополнительные подзапросы из цикла обработки аттрибутов и опций, так как все необходимые данные можно получить в одном запросе. Так же используются PHP указатели, что позволит обработать все данные в одном цикле. Все это позволит получить все необходимые данные за один запрос и быстро из обработать. 

 

В данном частном случае производительность увеличилась почти в 30 раз (очень много опций, значений опций и аттрибутов почти у каждого товара). 


public function getProductAttributes($product_id) {
	$product_attribute_group_data = array();

	$product_attribute_group_query = $this->db->query("SELECT a.attribute_id, ad.name as attribute_name, pa.text, ag.attribute_group_id, agd.name as attribute_group_name FROM " . DB_PREFIX . "product_attribute pa
	LEFT JOIN " . DB_PREFIX . "attribute a ON (pa.attribute_id = a.attribute_id)
	LEFT JOIN " . DB_PREFIX . "attribute_description ad ON (a.attribute_id = ad.attribute_id)
	LEFT JOIN " . DB_PREFIX . "attribute_group ag ON (a.attribute_group_id = ag.attribute_group_id)
	LEFT JOIN " . DB_PREFIX . "attribute_group_description agd ON (ag.attribute_group_id = agd.attribute_group_id)
	WHERE pa.product_id = " . (int)$product_id . "
		AND ad.language_id = agd.language_id
		AND pa.language_id = agd.language_id
		AND agd.language_id = " . (int)$this->config->get('config_language_id') . "
	ORDER BY ag.sort_order, agd.name, a.sort_order, ad.name");

	$product_attribute_data = array();

	foreach ($product_attribute_group_query->rows as $product_attribute) {
		$product_attribute_data[$product_attribute['attribute_id']][] = array(
			'attribute_id' => $product_attribute['attribute_id'],
			'name'         => $product_attribute['attribute_name'],
			'text'         => $product_attribute['text']
		);

		$product_attribute_group_data[$product_attribute['attribute_group_id']] = array(
			'attribute_group_id' => $product_attribute['attribute_group_id'],
			'name'               => $product_attribute['attribute_group_name'],
		);

		$product_attribute_group_data[$product_attribute['attribute_group_id']]['attribute'] =& $product_attribute_data[$product_attribute['attribute_id']];

	}

	return $product_attribute_group_data;
}

public function getProductOptions($product_id) {
	$product_option_data = array();
    $product_option_query = $this->db->query("SELECT pov.product_option_value_id, pov.option_value_id, ovd.name as product_option_value_name, od.name as option_name, ov.image, pov.quantity, pov.subtract, pov.price, pov.price_prefix, pov.points, pov.points_prefix, pov.weight, pov.weight_prefix, pov.product_option_id, pov.option_id, o.type, po.required
        FROM " . DB_PREFIX . "product_option_value pov
        LEFT JOIN " . DB_PREFIX . "option_value ov ON (pov.option_value_id = ov.option_value_id)
        LEFT JOIN " . DB_PREFIX . "option_value_description ovd ON (ov.option_value_id = ovd.option_value_id)
        LEFT JOIN " . DB_PREFIX . "product_option po ON (pov.product_option_id = po.product_option_id)
        LEFT JOIN `" . DB_PREFIX . "option` o ON (po.option_id = o.option_id)
        LEFT JOIN " . DB_PREFIX . "option_description od ON (o.option_id = od.option_id)
        WHERE po.product_id = " . (int)$product_id . "
            AND od.language_id = " . (int)$this->config->get('config_language_id') . "
        ORDER BY o.sort_order, ov.sort_order");

    $product_option_value_data = array();

    foreach ($product_option_query->rows as $product_option) {

    	if (in_array($product_option['type'], array('select','radio','checkbox','image'))) {

            $product_option_value_data[$product_option['product_option_id']][] = array(
                'product_option_value_id' => $product_option['product_option_value_id'],
                'option_value_id'         => $product_option['option_value_id'],
                'name'                    => $product_option['product_option_value_name'],
                'image'                   => $product_option['image'],
                'quantity'                => $product_option['quantity'],
                'subtract'                => $product_option['subtract'],
                'price'                   => $product_option['price'],
                'price_prefix'            => $product_option['price_prefix'],
                'points'                  => $product_option['points'],
                'points_prefix'           => $product_option['points_prefix'],
                'weight'                  => $product_option['weight'],
                'weight_prefix'           => $product_option['weight_prefix']
            );

            $product_option_data[$product_option['option_id']] = array(
				'product_option_id'    => $product_option['product_option_id'],
				'option_id'            => $product_option['option_id'],
				'name'                 => $product_option['option_name'],
				'type'                 => $product_option['type'],
				'required'             => $product_option['required']
			);

			$product_option_data[$product_option['option_id']]['option_value'] =& $product_option_value_data[$product_option['product_option_id']];

    	}else{
    		$product_option_data[$product_option['option_id']] = array(
				'product_option_id' => $product_option['product_option_id'],
				'option_id'         => $product_option['option_id'],
				'name'              => $product_option['option_name'],
				'type'              => $product_option['type'],
				'option_value'      => $product_option['option_value'],
				'required'          => $product_option['required']
			);
    	}
    }

	return $product_option_data;
}

 

По аналогии поступил с админкой (только опции) и с модулем CSV Product Export. Будьте внимательны при использовании этого кода, он изменен, а значит и vqmod модификации, которые работают с этим участком кода могут работать не так как ожидается. 

Изменено пользователем halfhope
  • +1 9

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Спасибо. Как раз в тему, попробую сейчас на реальном магазине с 20К товарами

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

UPD: Накосячил слегка с аттрибутами:


public function getProductAttributes($product_id) {
	$product_attribute_group_data = array();

	$product_attribute_group_query = $this->db->query("SELECT a.attribute_id, ad.name as attribute_name, pa.text, ag.attribute_group_id, agd.name as attribute_group_name FROM " . DB_PREFIX . "product_attribute pa
	LEFT JOIN " . DB_PREFIX . "attribute a ON (pa.attribute_id = a.attribute_id)
	LEFT JOIN " . DB_PREFIX . "attribute_description ad ON (a.attribute_id = ad.attribute_id)
	LEFT JOIN " . DB_PREFIX . "attribute_group ag ON (a.attribute_group_id = ag.attribute_group_id)
	LEFT JOIN " . DB_PREFIX . "attribute_group_description agd ON (ag.attribute_group_id = agd.attribute_group_id)
	WHERE pa.product_id = " . (int)$product_id . "
		AND ad.language_id = agd.language_id
		AND pa.language_id = agd.language_id
		AND agd.language_id = " . (int)$this->config->get('config_language_id') . "
	ORDER BY ag.sort_order, agd.name, a.sort_order, ad.name");

	$product_attribute_data = array();

	foreach ($product_attribute_group_query->rows as $product_attribute) {
		$product_attribute_data[$product_attribute['attribute_group_id']][$product_attribute['attribute_id']] = array(
			'attribute_id' => $product_attribute['attribute_id'],
			'name'         => $product_attribute['attribute_name'],
			'text'         => $product_attribute['text']
		);

		$product_attribute_group_data[$product_attribute['attribute_group_id']] = array(
			'attribute_group_id' => $product_attribute['attribute_group_id'],
			'name'               => $product_attribute['attribute_group_name'],
		);

		$product_attribute_group_data[$product_attribute['attribute_group_id']]['attribute'] =& $product_attribute_data[$product_attribute['attribute_group_id']];

	}

	return $product_attribute_group_data;
}
Изменено пользователем halfhope
  • +1 2

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

и моё благодарю)

  • +1 1

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

У меня лог медленных запросов все также жалуется на этот запрос.

Товаров 1500 штук.

Таблица с атрибутами 28000 шт.

М.б. где индексы расставить дополнительные?

 

id     select_type     table     partitions     type     possible_keys     key     key_len     ref     rows     filtered     Extra     
1     SIMPLE     agd     NULL    ALL     PRIMARY     NULL    NULL    NULL    20     10.00     Using where; Using temporary; Using filesort
1     SIMPLE     ag     NULL    eq_ref     PRIMARY     PRIMARY     4     shop.agd.attribute_group_id     1     100.00     NULL
1     SIMPLE     a     NULL    ref     PRIMARY,attribute_group_id     attribute_group_id     4     shop.agd.attribute_group_id     3     100.00     Using where
1     SIMPLE     ad     NULL    eq_ref     PRIMARY,index2attr_lang     PRIMARY     8     shop.a.attribute_id,const     1     100.00     NULL
1     SIMPLE     pa     NULL    eq_ref     PRIMARY,attribute_id,language_id     PRIMARY     12     const,shop.a.attribute_id,const     1     100.00     NULL

 

 

Структура таблицы:

Table Create Table
attribute CREATE TABLE `attribute` (
 `attribute_id` int(11) NOT NULL AUTO_INCREMENT,
 `attribute_group_id` int(11) NOT NULL,
 `sort_order` int(3) NOT NULL,
 PRIMARY KEY (`attribute_id`),
 KEY `attribute_group_id` (`attribute_group_id`),
 KEY `sort_order` (`sort_order`)
) ENGINE=MyISAM AUTO_INCREMENT=39 DEFAULT CHARSET=utf8
attribute_description CREATE TABLE `attribute_description` (
 `attribute_id` int(11) NOT NULL,
 `language_id` int(11) NOT NULL,
 `name` varchar(64) NOT NULL,
 PRIMARY KEY (`attribute_id`,`language_id`),
 KEY `name` (`name`),
 KEY `index2attr_lang` (`language_id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8
attribute_group CREATE TABLE `attribute_group` (
 `attribute_group_id` int(11) NOT NULL AUTO_INCREMENT,
 `sort_order` int(3) NOT NULL,
 PRIMARY KEY (`attribute_group_id`),
 KEY `sort_order` (`sort_order`)
) ENGINE=MyISAM AUTO_INCREMENT=8 DEFAULT CHARSET=utf8
attribute_group_description CREATE TABLE `attribute_group_description` (
 `attribute_group_id` int(11) NOT NULL,
 `language_id` int(11) NOT NULL,
 `name` varchar(64) NOT NULL,
 PRIMARY KEY (`attribute_group_id`,`language_id`),
 KEY `name` (`name`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8
product_attribute CREATE TABLE `product_attribute` (
 `product_id` int(11) NOT NULL,
 `attribute_id` int(11) NOT NULL,
 `language_id` int(11) NOT NULL,
 `text` text NOT NULL,
 PRIMARY KEY (`product_id`,`attribute_id`,`language_id`),
 KEY `attribute_id` (`attribute_id`),
 KEY `language_id` (`language_id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8

 

 

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Для публикации сообщений создайте учётную запись или авторизуйтесь

Вы должны быть пользователем, чтобы оставить комментарий

Создать учетную запись

Зарегистрируйте новую учётную запись в нашем сообществе. Это очень просто!

Регистрация нового пользователя

Войти

Уже есть аккаунт? Войти в систему.

Войти

  • Похожий контент

    • От MaxD
      Скачать/Купить дополнение


      OpenCart Lightning
       

       
      OpenCart Lightning - это мод для ускорения работы магазинов. Он использует целый ряд технологий и ноу-хау.
      Работает со всеми версиями OpenCart и ocStore.
       
      Вот ссылка на демо-магазин с 20000 товаров на хостинге DigitalOcean за $5 - http://demo.devs.mx/lightning
      почти мгновенное открытие страниц оптимизировано для получения высоких показателей в новом Google PageSpeed Insigts (осень 2018) быстрая работа с большим количеством товаров и категорий повышение удобства навигации по магазину и рейтингов в поисковиках не надо настраивать и приглядывать, просто работает отпадает необходимость в дополнительных модах оптимизации или кеширования  
       
       
       
       
      Если вы залогинены в админку - страницы, на которые вы заходите - после этого перегенерируются. То есть, если вы хотите увидеть изменения - просто обновите страницу.
      В большинстве случаев нет необходимости очищать кеш вручную - все обновляется автоматически.
       
      После установки у вас будет 7 дней тестового периода, дальше надо будет купить лицензию.
      Про покупке есть возможность заказать платную проверку магазина и настройку Lightning.
       
      Внимание: OpenCart Lightning не работает на localhost, только на реальных интернет-серверах.
       
      Установка
      Загрузите lightning.ocmod.zip в инсталлятор, зайдите в Модификации и обновите их.
       
      Обновление
      1. Выключите Lightning.
      2. Очистите кеш Lightning.
      3. Зайдите в Модификации и удалите модификацию Lightning.
      4. Если вы обновляетесь с Lightning 1.xx или 2.хх, удалите папку system/lightning
      4. Установите новую версию Ligthning.
      5. Обновите Модификации.
      6. Включите Lightning.
      .
      Добавил MaxD Добавлено 04.12.2014 Категория Кэширование, сжатие, ускорение Системные требования Сайт разработчика http://lightning.devs.mx/ Старая цена Метод активации Автоматическая активация Ioncube Loader Нет OpenCart 3.0
      2.3
      2.2
      2.1
      2.0
      1.5.6.4
      1.5.6.3
      1.5.6.2
      1.5.6.1
      1.5.6
      1.5.4.1
      1.5.3.1 ocStore 3.0
      2.3
      2.2
      2.1
      1.5.5.1.2
      1.5.5.1.1
      1.5.5.1
      1.5.4.1.2
      1.5.4.1.1
      1.5.4.1
      1.5.3.1
      1.5.2.1
      1.5.1.3 OpenCart.Pro, ocShop Opencart.pro 2.3
      Opencart.pro 2.1
      OcShop 2.0.3.х
      OcShop 1.5.6.4.х  
    • От MaxD
      OpenCart Lightning - это мод для ускорения работы магазинов. Он использует целый ряд технологий и ноу-хау.
      Работает со всеми версиями OpenCart и ocStore.
       
      Вот ссылка на демо-магазин с 20000 товаров на хостинге DigitalOcean за $5 - http://demo.devs.mx/lightning
      почти мгновенное открытие страниц оптимизировано для получения высоких показателей в новом Google PageSpeed Insigts (осень 2018) быстрая работа с большим количеством товаров и категорий повышение удобства навигации по магазину и рейтингов в поисковиках не надо настраивать и приглядывать, просто работает отпадает необходимость в дополнительных модах оптимизации или кеширования  
       
       
       
       
      Если вы залогинены в админку - страницы, на которые вы заходите - после этого перегенерируются. То есть, если вы хотите увидеть изменения - просто обновите страницу.
      В большинстве случаев нет необходимости очищать кеш вручную - все обновляется автоматически.
       
      После установки у вас будет 7 дней тестового периода, дальше надо будет купить лицензию.
      Про покупке есть возможность заказать платную проверку магазина и настройку Lightning.
       
      Внимание: OpenCart Lightning не работает на localhost, только на реальных интернет-серверах.
       
      Установка
      Загрузите lightning.ocmod.zip в инсталлятор, зайдите в Модификации и обновите их.
       
      Обновление
      1. Выключите Lightning.
      2. Очистите кеш Lightning.
      3. Зайдите в Модификации и удалите модификацию Lightning.
      4. Если вы обновляетесь с Lightning 1.xx или 2.хх, удалите папку system/lightning
      4. Установите новую версию Ligthning.
      5. Обновите Модификации.
      6. Включите Lightning.
      .
    • От markimax
      990.00 руб
      Скачать/Купить дополнение


      Jet Cache - кеширование, оптимизация для магазинов

       

      Логин / пароль:
      demo / demo
       
      Документация  
      Более 10`000 интернет магазинов выбрали SEO CMS для работы
      SEO CMS JET CACHE :: Jet Cache - быстрая система кеширования страниц, контроллеров и методов моделей opencart

      Версия под opencart 3.x высылается по запросу
      Возможности
       
      - кеширует полностью страницы при полной интеграции с opencart (позволяет кешировать и для зарегистрированных пользователей и изменений корзины а также в зависимости от изменений в модулях)  
      - кеширует выбранные контроллеры (т е фактически  любые модули, будь то меню или т.п. а также полностью кеширует позиции (уникальная технология которая не реализовано ни в одном модуле кеширования для opencart) (с))  
      - кеширует методы моделей opencart (подсчет количества товаров и т п )  
      - простая установка и обновление  
      - гибкие настройки  
      - поддержка мультиязычности  
      - поддержка мультимагазинов  
      - поддержка протоколов https и http  
      - гибкая взаимосвязь с любым функционалом платформы SEO CMS  
      - совместимость с любой темой, любыми модулями, которые соответствуют стандартам программирования  
      - поддержка кеширования sitemap Чем модуль лучше других
       
      - уникальные технологии кеширования не имеющие аналогов в opencart (уникальная технология полной интеграции с opencart, в отличии от всех кешировщиков которые сделанны по технологии v2pc)  
      - модуль работает с любыми темами и модулями Требования
       
      Opencart 2.x или любая сборка на нем (ocStore, Opencart.PRO, или другие) PHP 5.3 или выше Модуль НЕ заменяет файлы системы Модуль НЕ использует ioncube  
      Совместимость модуля
       
      Opencart 2.x или любая сборка на нем (ocStore, Opencart.PRO, или другие) Любая тема или любые модули (которые сделаны без ошибок, согласно стандартов программирования или верстки) для оpencart 2.x  
      Установка, настройка
       
      Если пользователь хочет чтобы сотрудник службы технической поддержки проделал работу по установке и настройке модуля вместо пользователя на сервере пользователя, это уже услуга + 590 рублей  
      Лицензия Все права на модуль принадлежат разработчикам opencartadmin.com Условия использования лицензии: один домен - одна лицензия (покупка продукта для каждого домена). Условия использования лицензии - "на владельца". Далее... Добавил markimax Добавлено 15.03.2017 Категория Кэширование, сжатие, ускорение Системные требования PHP 5.3+ Сайт разработчика https://opencartadmin.com/seo-cms-jet-cache.html Старая цена 590 Метод активации Через официальный сайт дополнения Ioncube Loader Нет OpenCart 3.0
      2.3
      2.2
      2.1
      2.0
      1.5.6.4
      1.5.6.3
      1.5.6.2
      1.5.6.1
      1.5.6
      1.5.5.1
      1.5.5
      1.5.4.1
      1.5.3.1 ocStore 2.3
      2.2
      2.1 OpenCart.Pro, ocShop Opencart.pro 2.3
      Opencart.pro 2.1
      OcShop 2.0.3.х
      OcShop 1.5.6.4.х  
    • От Sha
      449.00 руб
      Скачать/Купить дополнение


      Layout Type, ускорение мобильной версии.
      Модуль для ускорения мобильной версии сайта.
      DEMO
      Подробней:
      Как сделать шаблон адаптивным? на мобильной версии скрыть "лишние" элементы.
      Как, что-бы при этом не пострадало usability? переместить модули и виджеты на другие позиции.
       
      Даже топовые шаблоны, поступают именно таким образом, элементы которые "не нужны" или наоборот необходимы только в мобильной версии: либо скрываются посредством css (display:none); либо перемещаются, хорошо если flexbox или bootstrap pull push но часто с помощью навешивания множества слушателей событий javascript. Даже адаптивность bootstrap основана на таких принципах.
      Всё это создаёт лишний "вес" и нагрузку, что конечно же замедляет работу сайта и заставляет процессор пользователя работать с повышенной нагрузкой шумя как майнинг ферма.
      Мы в наших продуктах пропагандируем использовать только то, что необходимо сейчас. И исходя из этих принципов нами был разработан
       
      модуль Мобильные схемы который позволит:
      уменьшить объём страницы,  избавится от лишнего JavaScript кода, избавится от css костылей,      и др.
           при этом даже улучшив
      адаптивность, гибкость в настройке и дружелюбность Вашего сайта!  
       
      Поддерживает встроенные схемы популярных модулей, например поддерживает SEOCMS.
      Большие скидки, для постоянных покупателей.
       
      Бесплатно модуль получить можно вместе с шаблоном Roundshop.
       
      FAQ
       
      Техническая поддержка
      доступна пользователям из списка покупателей.
      Если вы обращаетесь с просьбой разобраться в проблеме, то для экономии времени укажите:
      адрес сайта доступ в админ-панель доступ на FTP-сервер  
      По любым вопросам вы можете связаться с нами через:
      Личные сообщения на форуме; Режим работы с 10-00 до 18-00 по киевскому времени за исключением выходных и праздничных дней.
       
      Добавил Sha Добавлено 13.03.2018 Категория Кэширование, сжатие, ускорение Системные требования Сайт разработчика r.konotop.info Старая цена Метод активации Автоматическая активация Ioncube Loader Нет OpenCart 2.3
      2.2
      2.1 ocStore 2.3
      2.2
      2.1 OpenCart.Pro, ocShop Opencart.pro 2.3
      Opencart.pro 2.1
      OcShop 2.0.3.х  
    • От Sha
      Модуль для ускорения мобильной версии сайта.
      DEMO
      Подробней:
      Как сделать шаблон адаптивным? на мобильной версии скрыть "лишние" элементы.
      Как, что-бы при этом не пострадало usability? переместить модули и виджеты на другие позиции.
       
      Даже топовые шаблоны, поступают именно таким образом, элементы которые "не нужны" или наоборот необходимы только в мобильной версии: либо скрываются посредством css (display:none); либо перемещаются, хорошо если flexbox или bootstrap pull push но часто с помощью навешивания множества слушателей событий javascript. Даже адаптивность bootstrap основана на таких принципах.
      Всё это создаёт лишний "вес" и нагрузку, что конечно же замедляет работу сайта и заставляет процессор пользователя работать с повышенной нагрузкой шумя как майнинг ферма.
      Мы в наших продуктах пропагандируем использовать только то, что необходимо сейчас. И исходя из этих принципов нами был разработан
       
      модуль Мобильные схемы который позволит:
      уменьшить объём страницы,  избавится от лишнего JavaScript кода, избавится от css костылей,      и др.
           при этом даже улучшив
      адаптивность, гибкость в настройке и дружелюбность Вашего сайта!  
       
      Поддерживает встроенные схемы популярных модулей, например поддерживает SEOCMS.
      Большие скидки, для постоянных покупателей.
       
      Бесплатно модуль получить можно вместе с шаблоном Roundshop.
       
      FAQ
       
      Техническая поддержка
      доступна пользователям из списка покупателей.
      Если вы обращаетесь с просьбой разобраться в проблеме, то для экономии времени укажите:
      адрес сайта доступ в админ-панель доступ на FTP-сервер  
      По любым вопросам вы можете связаться с нами через:
      Личные сообщения на форуме; Режим работы с 10-00 до 18-00 по киевскому времени за исключением выходных и праздничных дней.
       
  • Последние посетители   0 пользователей онлайн

    Ни одного зарегистрированного пользователя не просматривает данную страницу

×

Важная информация

На нашем сайте используются файлы cookie и происходит обработка некоторых персональных данных пользователей, чтобы улучшить пользовательский интерфейс. Чтобы узнать для чего и какие персональные данные мы обрабатываем перейдите по ссылке. Если Вы нажмете «Я даю согласие», это означает, что Вы понимаете и принимаете все условия, указанные в этом Уведомлении о Конфиденциальности.