Кеширование

Общие вопросы по использованию второй версии фреймворка. Если не знаете как что-то сделать и это про Yii 2, вам сюда.
Ответить
Аватара пользователя
oleg1
Сообщения: 78
Зарегистрирован: 2013.10.23, 15:13

Кеширование

Сообщение oleg1 »

Скажите пожалуйста, когда я кеширую MYSQL-запросы, как написано в документации, например на 600 секунд.

$customer = $db->createCommand('SELECT * FROM customer WHERE id=1')->cache(600)->queryOne();

Почему при добавлении, например в таблицу customer нового значения, оно начинается выводиться сразу, а не через 600 секунд, когда истечет кеш ?
someweb
Сообщения: 552
Зарегистрирован: 2017.03.09, 10:12

Re: Кеширование

Сообщение someweb »

А как вы по id=1 находите новое значение?
Кэшируется запрос 'SELECT * FROM customer WHERE id=1'
Запроса 'SELECT * FROM customer WHERE id=OTHER_ID' в кэше не будет.
Чтобы правильно задать вопрос, нужно знать бо́льшую часть ответа. Роберт Шекли.
Аватара пользователя
oleg1
Сообщения: 78
Зарегистрирован: 2013.10.23, 15:13

Re: Кеширование

Сообщение oleg1 »

Это я пример взял из документации для примера вот здесь :
https://yiiframework.com.ua/ru/doc/guid ... hing-data/
Запрос у меня всегда одинаковый, никаких переменных в запросе нет. Но при добавлении в базу новых данных, они сразу появляются в результатах запроса, если все делать через "->cache(600)"
Аватара пользователя
Alexum
Сообщения: 683
Зарегистрирован: 2016.09.26, 10:00

Re: Кеширование

Сообщение Alexum »

Проблема в вашем запросе, разбирайтесь.
Аватара пользователя
Йож
Сообщения: 574
Зарегистрирован: 2015.08.26, 03:05

Re: Кеширование

Сообщение Йож »

В дебагере же все есть.. Сколько реальных запросов идет без кеша
Nex-Otaku
Сообщения: 831
Зарегистрирован: 2016.07.09, 21:07

Re: Кеширование

Сообщение Nex-Otaku »

Запрос из документации работает правильно. Ваш запрос не работает. Покажите свой код, будет понятно, что с ним не так.
Аватара пользователя
oleg1
Сообщения: 78
Зарегистрирован: 2013.10.23, 15:13

Re: Кеширование

Сообщение oleg1 »

Конкретно у меня вот такой вот запрос :

Код: Выделить всё

        $games = Yii::$app->db->createCommand("SELECT onf.*, seo.*,
                           FLOOR(TO_DAYS(NOW())-TO_DAYS(FROM_UNIXTIME(dateadded))) as putdate                           
                           FROM on_files AS onf
                           LEFT JOIN seotext AS seo ON onf.fileid = seo.item_id AND seo.class = 'app\\\models\\\OnFiles'
                           INNER JOIN vote_aggregate as va ON onf.fileid = va.target_id  			               
                           WHERE onf.status = '1' 
                           ORDER BY va.positive DESC")
            ->cache(3600)
            ->queryAll();
В дебагере да, на второй заход на страничку, этого запроса нет, но факт в том, что он не 3600 секунд кешируется, а намного меньше.

Но если я возьму кеширование не через Yii, а просто через php, типа вот такого, то все работает :

Код: Выделить всё

   if($oCache->getData("new_query2")) { // если в мемкеше есть ключ	         
        $most_popular_rowarr3 = $oCache->getData("new_query2"); // получение данных    
    } else {        
		$most_nov = DB::query("SELECT icon,title,title_en, fileid, rating, rating_n, 
                                           FLOOR(TO_DAYS(NOW())-TO_DAYS(FROM_UNIXTIME(dateadded))) as putdate,
                                           timesplayed, video, description, description_en
                                           FROM on_files 
                                           WHERE status = '1'
                                           ORDER BY timesplayed DESC");
     while($row3 = mysqli_fetch_assoc($most_nov))      $most_popular_rowarr3[] = $row3;

     $oCache->setData("new_query2", $most_popular_rowarr3); // сохранение данных            
    }
skynin
Сообщения: 400
Зарегистрирован: 2017.12.12, 10:09

Re: Кеширование

Сообщение skynin »

Думается дело в NOW()

Попробуйте вынести вычисление FLOOR(TO_DAYS(NOW()) до запроса

P.S.
Хотя, посмотрел, не должно влиять

Код: Выделить всё

// yii\db\Command
$cacheKey = [
                    __CLASS__,
                    $method,
                    $fetchMode,
                    $this->db->dsn,
                    $this->db->username,
                    $rawSql ?: $rawSql = $this->getRawSql(),
                ];
                $result = $cache->get($cacheKey);
просто я для кеширования запросов использую встроенный в MySQL кешер, а он не любит NOW

для отлова почему не работает кеширование запроса - я бы в queryInternal своего отладочного вывода добавил.
думаю, что-то все же меняется у вас при формировании ключа.
Не желайте странного, и не будет у вас головной боли чтобы достичь этого странного.
Тем более что окажется что оно вам и не нужно было, странное это.
chesar
Сообщения: 514
Зарегистрирован: 2013.04.10, 17:49

Re: Кеширование

Сообщение chesar »

https://github.com/yiisoft/yii2/blob/ma ... %BE%D0%B2-

Код: Выделить всё

$games = Yii::$app->cache(function($db) {
 return $db->createCommand("SELECT onf.*, seo.*,
   FLOOR(TO_DAYS(NOW())-TO_DAYS(FROM_UNIXTIME(dateadded))) as putdate
   FROM on_files AS onf
   LEFT JOIN seotext AS seo ON onf.fileid = seo.item_id AND seo.class = 'app\\\models\\\OnFiles'
   INNER JOIN vote_aggregate as va ON onf.fileid = va.target_id
   WHERE onf.status = '1'
   ORDER BY va.positive DESC")->queryAll();
});
Nex-Otaku
Сообщения: 831
Зарегистрирован: 2016.07.09, 21:07

Re: Кеширование

Сообщение Nex-Otaku »

Судя по приведённому коду, всё должно работать. Значит, где-то ещё ошибка.

Может при добавлении очистка кеша производится?
zelenin
Сообщения: 10596
Зарегистрирован: 2013.04.20, 11:30

Re: Кеширование

Сообщение zelenin »

skynin писал(а): 2018.02.08, 11:48 Думается дело в NOW()

Попробуйте вынести вычисление FLOOR(TO_DAYS(NOW()) до запроса

P.S.
Хотя, посмотрел, не должно влиять

Код: Выделить всё

// yii\db\Command
$cacheKey = [
                    __CLASS__,
                    $method,
                    $fetchMode,
                    $this->db->dsn,
                    $this->db->username,
                    $rawSql ?: $rawSql = $this->getRawSql(),
                ];
                $result = $cache->get($cacheKey);
просто я для кеширования запросов использую встроенный в MySQL кешер, а он не любит NOW
что такое встроенный в mysql кэшер?
skynin
Сообщения: 400
Зарегистрирован: 2017.12.12, 10:09

Re: Кеширование

Сообщение skynin »

zelenin писал(а): 2018.02.08, 13:41 что такое встроенный в mysql кэшер?
The MySQL Query Cache
Не желайте странного, и не будет у вас головной боли чтобы достичь этого странного.
Тем более что окажется что оно вам и не нужно было, странное это.
zelenin
Сообщения: 10596
Зарегистрирован: 2013.04.20, 11:30

Re: Кеширование

Сообщение zelenin »

skynin писал(а): 2018.02.08, 13:44
zelenin писал(а): 2018.02.08, 13:41 что такое встроенный в mysql кэшер?
The MySQL Query Cache
это совсем не то же, что и кэш приложения. Это внутренняя оптимизация. Расчитывать на него не стоит от слова совсем. Даже без учета того, что это deprecated и выпилится в следующей версии.
skynin
Сообщения: 400
Зарегистрирован: 2017.12.12, 10:09

Re: Кеширование

Сообщение skynin »

zelenin писал(а): 2018.02.08, 13:47 это совсем не то же, что и кэш приложения.
Конечно не то же.
Просто часто и не потребуется кеширование данных на уровне приложения.
zelenin писал(а): 2018.02.08, 13:47 Это внутренняя оптимизация. Расчитывать на него не стоит от слова совсем.
Не совсем понятно что такое - внутренняя оптимизация.

Использую много лет.
Иногда просто нужно схему БД проектировать с его учетом - чтобы не сбрасывался.
zelenin писал(а): 2018.02.08, 13:47 Даже без учета того, что это deprecated и выпилится в следующей версии.
это да, в 8.0 его не будет.
значит не надо спешить переходить на 8ую версию.
в 5.7 прекрасно работает.

Не смотрел что там с ним будет у MariaDB.
Он очень удобен для сценариев где преимущественно чтение из БД.

Выпиливают его потому что при работе на запись, он не только бесполезен, а еще и притормаживает, из-за монопольного захвата памяти для очистки.
MySQL 8.0: Retiring Support for the Query Cache

Но не суть, с NOW() он все равно не работал бы.
Не желайте странного, и не будет у вас головной боли чтобы достичь этого странного.
Тем более что окажется что оно вам и не нужно было, странное это.
Ответить