如何缓存db_query()的结果?


9

我曾经views_get_view_result()从视图中获取结果,因为当时很方便。查询结果很少改变;我可以将视图缓存使用6天。

如果我想将其转换为db_query()如何启用缓存的调用?

Answers:


9

如果使用视图或db_query(),则缓存不会太慢。缓存的工作原理始终相同,当缓存未命中时如何获取数据完全取决于您。

  1. 构建一个高速缓存ID以标识您的高速缓存条目。可以是简单的硬编码字符串,也可以是基于参数等的复杂字符串。
  2. 检查是否可以从缓存加载。
  3. 如果不是,请重建数据并将其以所需的到期时间放入缓存中。

要查看一些示例,您可以查看使用cache_get()函数,例如variable_initialize()

如果您的函数被多次调用,那么您可能希望将其与静态缓存结合使用,例如参见archiver_get_info()。而且,如果数据重建确实很慢,则可以像variable_initialize()一样使用锁定框架来防止它发生多次。

请注意,仅缓存一个缓慢的查询才有意义,因为cache_get()也是一个数据库查询,除非您使用像Memcache这样的备用缓存后端。

最后,Views已经内置了缓存,可以在您的视图中进行配置。因此,这也可能是一个选择。


击败我;)我将答案留给代码示例,但这是更有用的信息
Clive

我以为PDO实例不可序列化?
mpdonadio

1
不,它们不是,但这无关紧要。您不缓存pdo结果资源,而是缓存从该查询实际获取的任何数据结构。
贝迪尔(Berdir)2012年

我会说这很相关。@MotoTribe询问有关从中缓存结果的问题db_query(),而必须缓存from中的值,$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

除了Drupal提供的标准cache_set / cache_get机制之外,如果您使用MySQL作为数据库,则可以启用查询缓存,该缓存可以透明地缓存视图或任何其他数据库查询的结果。 mysqltuner可以帮助确定高速缓存大小的合适值。

只是请注意,如果您要对数据库进行大量写操作,则由于缓存无效策略的工作方式(写表会使所有SELECT FROM或JOIN该表的条目无效),查询缓存的效率会降低。

PostgreSQL也有一个缓存机制,但是我没有直接的经验。


3

我最近发现了“ 缓存操作”模块。使用此模块,您可以将视图缓存设置为“规则触发的缓存”,并创建用于使特定视图和视图显示上的缓存无效的规则。

例如,当创建具有特定内容类型的节点的视图时,可以清空该视图的缓存。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.