PHP最佳缓存MySQL结果的方法是什么?

33

我目前正在构建一个PHP框架(原创的,我知道),并且正在为其开发一些优化功能。我遇到的一个问题是:什么是最好的缓存MySQL结果的方法?我知道有些人会说,首先要优化你的MySQL等等,但假设查询需要1分钟才能运行且已经尽可能优化了,那么最好的缓存方法是什么呢?

我的第一个想法是,也许可以循环遍历结果,将它们添加到一个数组中...序列化它们然后存储在文件中。由于创建缓存只发生一次,如果数组包含100万个结果,我可以容忍序列化函数的开销。然而,在每个页面加载时加载缓存文件,然后反序列化数组,可能会对性能产生影响。

那么在缓存时,改为以 PHP 可读的数组形式写入文件,而不是序列化结果并写入文件,是否更好呢?这样在加载时就没有 unserialize 的开销了。

还有其他(更快的)缓存慢速查询以便频繁使用的方法吗?

4个回答

19
如果这是一个简单的数组,那么您可以使用var_export()而不是序列化它(用适当的""包裹它),并将其写入.php文件;然后在脚本中包含(include())。最好在htdocs树之外编写它,仅适用于内存缓存认为过多的大量数据。

这个主意太棒了,我的相形见绌。我觉得我会在我现有的自制解决方案中实现类似的东西。 - Dan Lugg
如果你想避免序列化,这可能是框架内最好的方法。虽然我怀疑序列化会有太多开销。但序列化将显著减少缓存文件大小。 - sreimer

15

Memcached

我总是尝试至少自己创建一次解决方案,以更好地掌握在大多数情况下正在发生的事情。当我创建自己的缓存解决方案时,我基本上做了你所说的事情。

// serialize an array of all results
$serialzedData = serialize($resultData);

// set TTL (60 seconds) and create cache filename with timestamp
$ttl = 60;
$cacheFilename = $ttl . '_' . time() . '_' . md5($sqlQuery)

// dump
file_put_contents($cacheFilename, $serializedData);

在查询执行前,它会搜索 cache 目录中与查询哈希匹配的文件。如果有匹配的文件,则会测试 timestamp + ttl <= current_time,如果为真,则返回未序列化的文件内容。否则,覆盖它。


2
昨天我做了类似的事情,试图减少一些特定查询所带来的影响,但实际上并没有太大帮助。我认为序列化、处理文件(无论是读取、写入还是其他操作)、反序列化等引入的开销足以使其变得缓慢,因此这样做并不值得。 - rg88
1
以上解决方案可能在表更新/插入频繁的情况下无法正常工作。在需要实时数据的实时/关键应用程序中,即使60秒也不足够,并且可能返回旧数据而不是更新后的数据。您可以使用MySQL UDF并调用php脚本来使插入/更新/删除触发器失效以使缓存文件失效。通过这种方式,您可以确保没有旧的缓存文件驻留在您的目录中,您可能不需要使用60秒时间。UDF和触发器可能是一种方法... - Mohammad Sharaf Ali
当然,@SURFER-TM,这个简单的例子只是为了帮助理解缓存工作流程。今天,我会结合临时记忆(在适用的情况下)和 Redis 作为更长TTL的后备存储。 - Dan Lugg
尝试一下MySQL UDF和触发器。你肯定会喜欢它的... - Mohammad Sharaf Ali

4

MySQL缓存查询结果,也许你应该增加MySQL查询缓存大小?或者在独立表中缓存大查询的结果?


3
谷歌搜索Memcache,这应该能帮助你找到正确的方向。

我理解得没错吧,memcache是一个需要在服务器上预先安装的编译库,对吗?如果是这样,那么我不能期望每个使用该框架的人都已经安装了它:/ - Ozzy
或者使用Redis,但人们很少能够访问Redis,而能够访问Memcache或APC的可能性更大。 - Mark Baker
1
@adam-peck APC通常比memcache更快,因为它不需要从(外部)服务器发出请求,所以没有网络延迟。 - Mark Baker
APC 用于缓存 PHP 字节码,以避免调用解释器。你不能说 APC 比 Memcache 快,因为你忽略了它们的工作方式。@Ozzy - 是的,Memcache 不必安装在目标机器上。然而,在通用服务器上,它是缓存 MySQL 结果的 最佳 方法(虽然还有其他方法,比如将整个 MySQL 数据集转储到内存中,然后使用 HandlerSocket,这样就可以通过主键直接访问 InnoDB 数据,但需要一个巨型机器)。 - Furicane
4
Memcache 和 APC 不能相互比较,它们各自实现两种不同的目标。 - dtbarne
显示剩余4条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接