什么是更快的file_exists或数据库检索


Whats faster file_exists or DB retrieval?

我目前正在调整我们为网站存储图像的方式。对于每个用户,我都想看看他们是否有个人资料图像,我通过检查文件是否存在于他们的文件夹结构中来做到这一点。这比在DB表中存储/检索图像名称更快吗?

我当前的file_exists代码如下所示:

$gender = ($gender == 1) ? 'female' : 'male';
$filename = SITE_ROOT . $this->img_url . $user_id . 'medium_thumb.jpg';
if (file_exists($filename)) {
    $filename = $this->img_url . $user_id . 'medium_thumb.jpg?v=' . time();
}
else {
    $filename = '/images/'.$gender.'.jpg';
}       
return $filename

我建议您使用file_exists(),即使文件名完全存储在数据库中——当错误导致数据库与文件系统不同步时,这将给您一个合理的回退。对这种事情有多个级别的错误处理是很好的。

既然如此,这个问题就没有必要了,因为在任何一种情况下都会使用file_exists()

此外,我建议抵制对代码进行微优化的诱惑。除非你正在进行大量的file_exists()调用,否则它不会对你的程序速度产生巨大的影响。在这个水平上调整你的表现通常是不必要的。

如果您担心代码的性能,请使用XDebug等评测工具来显示真正的性能瓶颈在哪里。你会有一些,但我保证它们不会出现在你在这里看到的代码中,除非它是循环的。

我认为file_exists要快得多。在使用sql时,您必须访问驱动程序等,file_exists是一个系统操作。

不要将所有图像存储在一个文件夹中;使用子文件夹-否则会有I/O造成的巨大性能打击(当你有10k以上的文件时,将是可通知的;有100k以上文件将是巨大的)

确保图像由轻量级web服务器(例如nginx)提供,而不是由apache提供,因为apache占用了太多资源。

现在是问题。一般来说,文件系统会更快。然而,文件系统很难跨不同的服务器进行扩展。例如,如果你有两个网络服务器,你将从哪一个服务器提供化身?您需要复制所有服务器上的所有文件,或者使用共享磁盘,或者使用分布式文件系统。因此,您不仅要记住性能,还要记住水平可伸缩性。

此外,您还可以为文件使用缓存,例如Varnish

在我看来,从短期来看,您的方法会更快。但是,如果您从数据库中获取图像名称并将其存储在会话中,那么从长远来看,这将更快,因为您可以每次从会话中检索该页面访问的值,而不是检查服务器上是否存在文件。

由于答案取决于这么多变量,我建议运行一个简单的测试来回答你的问题"哪个更好?"和相关问题"好多少?":

使用curl(或您最喜欢的自动HTTP客户端)对基于文件的代码进行1000次访问,并测量客户端所花费的时间和服务器端所消耗的资源,然后对基于DB的代码进行同样的操作。

如果值很小,请多次运行测试(或者可能将测试大小增加到10000)。

我认为,查询数据库将花费更多时间,因为最终它也会进入磁盘。

我的意思是,如果你检查磁盘,你有一个操作,但对于数据库,你连接到数据库,然后它转到磁盘(存储数据库文件的地方)。所以,文件系统应该更快(不过我还没有对它进行基准测试!)。