Como faço para armazenar em cache o resultado de db_query ()?

9

Eu costumava views_get_view_result()obter resultados de uma exibição porque era conveniente naquele momento. O resultado da consulta raramente muda; Eu poderia usar o cache de visualizações por 6 dias.

Se eu quisesse convertê-lo em uma chamada para db_query()como habilitar o cache?

uwe
fonte

Respostas:

9

Não importa para armazenamento em cache se você usa views ou db_query (). O armazenamento em cache funciona sempre da mesma maneira, a forma como os dados são buscados quando o cache falha é totalmente sua.

  1. Crie um ID de cache para identificar sua entrada de cache. Pode ser uma sequência simples, codificada ou algo complexo com base em argumentos e assim por diante.
  2. Verifique se pode carregar do cache.
  3. Caso contrário, recrie os dados e coloque-os no cache com o tempo de expiração desejado.

Para ver alguns exemplos, você pode examinar as funções que usam cache_get () , por exemplo variable_initialize () .

Se sua função for chamada várias vezes, provavelmente você deseja combiná-la com um cache estático, veja por exemplo archiver_get_info () . E se a reconstrução dos dados for realmente lenta, você poderá impedir que isso ocorra várias vezes usando a estrutura de bloqueio, como o variable_initialize ().

Observe que o cache de uma única consulta só faz sentido se for lenta, porque cache_get () também é uma consulta db, a menos que você use um backend de cache alternativo como o Memcache.

E, por último, o Views já possui armazenamento em cache embutido e pode ser configurado em sua exibição. Portanto, isso também pode ser uma opção.

Berdir
fonte
Bata-me;) Vou deixar minha resposta como um exemplo de código, mas essa é uma informação muito mais útil
Clive
Eu pensei que instâncias PDO não eram serializáveis?
mpdonadio
1
Não, eles não são, mas isso não é relevante. Você não armazena em cache o recurso de resultado pdo, armazena em cache quaisquer estruturas de dados que realmente buscar nessa consulta.
Berdir
Eu diria que é muito relevante. O @MotoTribe estava perguntando sobre os resultados do armazenamento em cache db_query(), e ter que armazenar em cache o valor de $results->fetchAll()e não $resultsé a chave para realmente fazê-lo funcionar.
mpdonadio
7

Eu não acho que a camada de banco de dados tenha algum mecanismo de cache embutido (embora eu possa estar errado), mas você poderia fazer uso da API de cache padrão.

Este é apenas um exemplo básico que armazenará em cache os resultados de uma consulta para obter nós de um determinado tipo:

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'));
}
Clive
fonte
3

Além do mecanismo padrão cache_set / cache_get que o Drupal fornece, se você estiver usando o MySQL como seu banco de dados, poderá ativar o cache de consultas , que pode armazenar em cache os resultados das visualizações ou qualquer outra consulta de banco de dados de forma transparente. O mysqltuner pode ajudar a descobrir bons valores para o tamanho do cache.

Observe que, se você estiver gravando muito no banco de dados, o cache de consultas se tornará menos eficaz devido à maneira como a estratégia de invalidação de cache funciona (uma gravação em uma tabela invalida todas as entradas que SELECT FROM ou JOIN nessa tabela).

Também existe um mecanismo de cache para o PostgreSQL , mas não tenho experiência direta com ele.

mpdonadio
fonte
3

Eu descobri recentemente o módulo Ações de cache . Com este módulo, você pode definir o cache da visualização como Cache acionado por regras e criar uma regra para invalidar o cache em visualizações e exibições específicas.

Por exemplo, o cache de uma exibição que lista nós de um tipo de conteúdo específico pode ser esvaziado quando um novo nó é criado para esse tipo de conteúdo.

weekbeforenext
fonte