BuslikDrev

Правильно-ли закэшировал запрос?

Recommended Posts

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

 

Мой запрос без кэша:

Скрытый текст

	// вывод производителей
	public function getManufacturers($parent_id = 0) {
		// запрос к БД
		$query = $this->db->query("SELECT *, IF(md.name > '', md.name, m.name) AS name FROM " . DB_PREFIX . "manufacturer m LEFT JOIN " . DB_PREFIX . "manufacturer_description md ON (m.manufacturer_id = md.manufacturer_id) LEFT JOIN " . DB_PREFIX . "manufacturer_to_store m2s ON (m.manufacturer_id = m2s.manufacturer_id) WHERE m.parent_id = '" . (int)$parent_id . "' AND md.language_id = '" . (int)$this->config->get('config_language_id') . "' AND m2s.store_id = '" . (int)$this->config->get('config_store_id') . "' AND m.status = '1' ORDER BY m.sort_order, LCASE(md.name)");
		// отдаём полученные данные в контроллер
		return $query->rows;
	}

 

 

Мой запрос с кэшем:

Скрытый текст

	// вывод производителей
	public function getManufacturers($parent_id = 0) {
		// файл кэша пустой, либо его нет и не будет
		$manufacturer_data = array();
		
		// загружаем файл кэша
		$cache_data = $this->cache->get('getManufacturers.' . (int)$this->config->get('config_language_id') . '.' . (int)$this->config->get('config_store_id'));
		
		// если файла кэша нету
		if (!$cache_data) {
			// запрос к БД
			$query = $this->db->query("SELECT *, IF(md.name > '', md.name, m.name) AS name FROM " . DB_PREFIX . "manufacturer m LEFT JOIN " . DB_PREFIX . "manufacturer_description md ON (m.manufacturer_id = md.manufacturer_id) LEFT JOIN " . DB_PREFIX . "manufacturer_to_store m2s ON (m.manufacturer_id = m2s.manufacturer_id)	WHERE md.language_id = '" . (int)$this->config->get('config_language_id') . "' AND m2s.store_id = '" . (int)$this->config->get('config_store_id') . "' AND m.status = '1' ORDER BY m.sort_order, LCASE(md.name)");
			// отдаём данные из БД в файл кэша
			$this->cache->set('getManufacturers.' . (int)$this->config->get('config_language_id') . '.' . (int)$this->config->get('config_store_id'), $query->rows);
			// загружаем файл кэша повторно
			$cache_data = $this->cache->get('getManufacturers.' . (int)$this->config->get('config_language_id') . '.' . (int)$this->config->get('config_store_id'));
		}
		
		// если файл кэша есть
		if ($cache_data) {
			// выгрузка данных из файла кэша
			foreach ($cache_data as $row) {
				// отсеиваем нужные данные
				if ($row['parent_id'] == $parent_id) {
					// отдаём полученные данные в $manufacturer_data
					$manufacturer_data[$row['manufacturer_id']] = $row;
				}
			}
		}
		
		// отдаём полученные данные в контроллер
		return $manufacturer_data;
	}

 

 

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


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

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

В общем такой код выходит:
 

Скрытый текст

	// вывод производителей
	public function getManufacturers($parent_id = 0) {
		// файл кэша пустой, либо его нет и не будет
		$manufacturer_data = array();
		
		// загружаем файл кэша
		$cache_data = $this->cache->get('getManufacturers.' . (int)$parent_id . '.' . (int)$this->config->get('config_language_id') . '.' . (int)$this->config->get('config_store_id'));
		
		// если файла кэша нету
		if (!$cache_data) {
			// запрос к БД
			$manufacturer_data = $this->db->query("SELECT *, IF(md.name > '', md.name, m.name) AS name FROM " . DB_PREFIX . "manufacturer m LEFT JOIN " . DB_PREFIX . "manufacturer_description md ON (m.manufacturer_id = md.manufacturer_id) LEFT JOIN " . DB_PREFIX . "manufacturer_to_store m2s ON (m.manufacturer_id = m2s.manufacturer_id) WHERE m.parent_id = '" . (int)$parent_id . "' md.language_id = '" . (int)$this->config->get('config_language_id') . "' AND m2s.store_id = '" . (int)$this->config->get('config_store_id') . "' AND m.status = '1' ORDER BY m.sort_order, LCASE(md.name)")->rows;
			// отдаём данные из БД в файл кэша
			$this->cache->set('getManufacturers.' . (int)$parent_id . '.' . (int)$this->config->get('config_language_id') . '.' . (int)$this->config->get('config_store_id'), $manufacturer_data);
		}
		
		// если файл кэша есть
		if ($cache_data) {
			// выгрузка данных из файла кэша
			$manufacturer_data = $cache_data;
		}
		
		// отдаём полученные данные в контроллер
		return $manufacturer_data;
	}

 

 

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


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

Добрый день.

Зачем изобретать велосипед. Пример кода из модели ocStrore 2.3

$manufacturer_data = $this->cache->get('manufacturer.' . (int)$this->config->get('config_language_id').'.'. (int)$this->config->get('config_store_id'));

if (!$manufacturer_data) {
    $query = $this->db->query("SELECT * FROM " . DB_PREFIX . "manufacturer m LEFT JOIN " . DB_PREFIX . "manufacturer_to_store m2s ON (m.manufacturer_id = m2s.manufacturer_id) LEFT JOIN " . DB_PREFIX . "manufacturer_description md ON (m.manufacturer_id = md.manufacturer_id) WHERE md.language_id = '" . (int)$this->config->get('config_language_id') . "' && m2s.store_id = '" . (int)$this->config->get('config_store_id') . "' ORDER BY md.name");

    $manufacturer_data = $query->rows;

    $this->cache->set('manufacturer.' . (int)$this->config->get('config_language_id') . '.'. (int)$this->config->get('config_store_id'), $manufacturer_data);
}

return $manufacturer_data;

P.S.: В штатном функционале запросы с параметрами не кешируются. Что бы кэш не рос бешенными темпами.

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


Ссылка на сообщение
Поделиться на других сайтах
7 часов назад, mpn2005 сказал:

Добрый день.

Зачем изобретать велосипед. Пример кода из модели ocStrore 2.3


$manufacturer_data = $this->cache->get('manufacturer.' . (int)$this->config->get('config_language_id').'.'. (int)$this->config->get('config_store_id'));

if (!$manufacturer_data) {
    $query = $this->db->query("SELECT * FROM " . DB_PREFIX . "manufacturer m LEFT JOIN " . DB_PREFIX . "manufacturer_to_store m2s ON (m.manufacturer_id = m2s.manufacturer_id) LEFT JOIN " . DB_PREFIX . "manufacturer_description md ON (m.manufacturer_id = md.manufacturer_id) WHERE md.language_id = '" . (int)$this->config->get('config_language_id') . "' && m2s.store_id = '" . (int)$this->config->get('config_store_id') . "' ORDER BY md.name");

    $manufacturer_data = $query->rows;

    $this->cache->set('manufacturer.' . (int)$this->config->get('config_language_id') . '.'. (int)$this->config->get('config_store_id'), $manufacturer_data);
}

return $manufacturer_data;

P.S.: В штатном функционале запросы с параметрами не кешируются. Что бы кэш не рос бешенными темпами.

 

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

Здесь мои конечные варианты:

 

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


Ссылка на сообщение
Поделиться на других сайтах
10 минут назад, BuslikDrev сказал:

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

Всё зависит от задачи.

Если например это меню, то лучше кэшировать сразу целиком в контроллере.

 

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


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

Создайте аккаунт или войдите для комментирования

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

Создать аккаунт

Зарегистрируйтесь для получения аккаунта. Это просто!

Зарегистрировать аккаунт

Войти

Уже зарегистрированы? Войдите здесь.

Войти сейчас

  • Сейчас на странице   0 пользователей

    Нет пользователей, просматривающих эту страницу