我见过几个数据库缓存引擎,它们都非常笨(即:keep this query cached for X minutes
),并且需要在执行10/DELETE
查询后手动删除整个缓存存储库。智能(?)数据库缓存
约2〜3年前,我开发了一个替代DB缓存系统的一个项目我工作,这个想法基本上是使用正则表达式来查找有关特定SQL查询表(S):
$query_patterns = array
(
'INSERT' => '/INTO\s+(\w+)\s+/i',
'SELECT' => '/FROM\s+((?:[\w]|,\s*)+)(?:\s+(?:[LEFT|RIGHT|OUTER|INNER|NATURAL|CROSS]\s*)*JOIN\s+((?:[\w]|,\s*)+)\s*)*/i',
'UPDATE' => '/UPDATE\s+(\w+)\s+SET/i',
'DELETE' => '/FROM\s+((?:[\w]|,\s*)+)/i',
'REPLACE' => '/INTO\s+(\w+)\s+/i',
'TRUNCATE' => '/TRUNCATE\s+(\w+)/i',
'LOAD' => '/INTO\s+TABLE\s+(\w+)/i',
);
我知道这些正则表达式可能有一些缺陷(当时我的正则表达式技能很绿),显然不匹配嵌套查询,但是因为我从来没有使用它们,这对我来说不是问题。
不管怎样,找到相关表我会按字母顺序进行排序,并与以下命名约定高速缓存储存库创建一个新的文件夹后:
+table_a+table_b+table_c+table_...+
在SELECT
查询的情况下,我会获取结果从数据库中,serialize()
并将其存储在适当的缓存文件夹,所以例如下面的查询结果:
SELECT `table_a`.`title`, `table_b`.`description` FROM `table_a`, `table_b` WHERE `table_a`.`id` <= 10 ORDER BY `table_a`.`id` ASC;
将存储在:
/cache/+table_a+table_b+/079138e64d88039ab9cb2eab3b6bdb7b.md5
MD5是查询本身。在后续的SELECT查询结果将是微不足道的提取。
在任何其他类型的写入查询(INSERT
,REPLACE
,UPDATE
,DELETE
等)的情况下我会3210都在他们的名字了+matched_table(s)+
的文件夹全部删除所有文件内容。这样就不需要删除整个缓存,只需删除受影响和相关表所使用的缓存。
该系统工作得很好,性能的差异是可见的 - 虽然该项目有更多的阅读查询比写查询。从那时起,我开始使用交易,FK CASCADE UPDATES
/DELETES
,并且从来没有时间来完善系统以使其适用于这些功能。
我以前用MySQL Query Cache,但是我必须说性能甚至没有比较。
我想知道:我是唯一一个在这个系统中看到美丽的人吗?有没有我可能没有意识到的瓶颈?为什么流行的框架如CodeIgniter和Kohana(我不知道Zend Framework)有这样基本的DB缓存系统?
更重要的是,你认为这是一个值得追求的功能吗?如果是,有什么我可以做/使用到使它更快(我主要关注的是磁盘I/O和(德)序列化的查询结果)?
我感谢所有的输入,谢谢。
我会说增加更多的内存到你的SQL框,让它担心缓存本身。 – DmitryK 2010-01-07 12:56:18
@DmitryK:就像我之前说过的,我过去使用过MySQL查询缓存,但是我的系统提供了更好的性能(不知道为什么)。 – 2010-01-07 13:21:22
+1用于询问自己和自己的方法。这是一个非常重要的事情,国际海事组织! – nickf 2010-01-08 00:01:42