Как мне кэшировать результат db_query ()?

9

Я имел обыкновение views_get_view_result()получать результаты от представления, потому что это было удобно в то время. Результат запроса редко изменяется; Я мог бы использовать кэширование просмотров в течение 6 дней.

Если бы я хотел преобразовать его в вызов, db_query()как я могу включить кэширование?

Уве
источник

Ответы:

9

Не имеет значения для кэширования, если вы используете views или db_query (). Кэширование работает всегда одинаково, то, как данные выбираются, когда кэш пропускает, полностью зависит от вас.

  1. Создайте идентификатор кэша, чтобы идентифицировать вашу запись в кэше. Может быть простой, жестко закодированной строкой или чем-то сложным, основанным на аргументах и ​​так далее.
  2. Проверьте, можете ли загрузить из кеша.
  3. Если нет, пересоберите данные и поместите их в кеш с желаемым сроком действия.

Чтобы увидеть некоторые примеры, вы можете взглянуть на функции, которые используют cache_get () , например variable_initialize () .

Если ваша функция вызывается несколько раз, вы, вероятно, захотите объединить ее со статическим кешем, см., Например, archiver_get_info () . И если перестройка данных действительно медленная, вы можете предотвратить ее многократное использование, используя платформу блокировки, как variable_initialize ().

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

И наконец, в представлениях уже встроено кэширование, и его можно настроить в своем представлении. Так что это может быть вариант.

Berdir
источник
Удивите меня;) Я оставлю свой ответ в качестве примера кода, но это гораздо более полезная информация
Клайв
Я думал, что экземпляры PDO не были сериализуемы?
mpdonadio
1
Нет, это не так, но это не актуально. Вы не кэшируете ресурс результата pdo, вы кэшируете любые структуры данных, которые вы фактически извлекаете из этого запроса.
Бердир
Я бы сказал, что это очень актуально. @MotoTribe спрашивал о кешировании результатов db_query()и необходимости кэшировать значение, $results->fetchAll()а не $resultsявляется ключом к тому, чтобы заставить его работать.
mpdonadio
7

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

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

function MYMODULE_get_nodes_by_type($type) {
  // Setup a cache ID
  $cid = 'MYMODULE:node_types:' . $type;

  // If a cached entry exists, return it
  if ($cached = cache_get($cid)) {
    return $cached->data;
  }

  // Otherwise load the data
  $data = db_query('SELECT * FROM {node} WHERE type = :type', array(':type' => $type))->fetchAll();

  // And cache it
  cache_set($cid, $data, 'cache', strtotime('+6 days'));
}
Клайв
источник
3

В дополнение к стандартному механизму cache_set / cache_get , который предоставляет Drupal, если вы используете MySQL в качестве базы данных, вы можете включить кэш запросов , который может прозрачно кэшировать результаты просмотров или любые другие запросы к базе данных. mysqltuner может помочь в определении хороших значений размера кэша.

Просто отметьте, что если вы делаете много записи в базу данных, то кэширование запросов становится менее эффективным из-за того, как работает стратегия аннулирования кэша (запись в таблицу делает недействительными все записи, которые ВЫБИРАЮТ ОТ или ПРИСОЕДИНЯЮТСЯ к этой таблице).

Существует также механизм кэширования для PostgreSQL , но я не имею прямого опыта с ним.

mpdonadio
источник
3

Недавно я обнаружил модуль Cache Actions . С помощью этого модуля вы можете установить для кэширования представлений значение «Кэш, запускаемый правилами», и создать правило для аннулирования кэша в определенных представлениях и представлениях представлений.

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

weekbeforenext
источник