PHP 性能 strpos 文件名或 MySQL 查询
PHP performance strpos filename or MySQL query
我在服务器上存储了一些高分辨率文件(如果重要的话,100K+)并将它们组织在不同的画廊中。当有人访问画廊时,我只显示缩略图和图像的低分辨率版本,在某些情况下会加水印,而在其他情况下则不会。现在由于我说的是大量图片,画廊页面上显示的低分辨率版本在 X 天后从服务器中清除。如果有人确实访问了图库,并且服务器上不存在该文件的低分辨率版本,它会即时生成,但是当我生成低分辨率版本时,我可能需要为其添加水印或不添加水印。
目前,显示图像的脚本不执行任何 SQL 调用,它全部基于文件系统(如果文件存在等),是否为图像加水印的决定基于:
if (strpos($file_name,"FREE")===false){ //add watermark }else{ //just resize}
我的逻辑是,这比对文件名或文件 ID 进行 SQL 查询并检查它是否应该是无水印图像更高效。但是我觉得文件名中包含FREE这个词有点不方便。
如果我使用 SQL 查询而不是 strpos,我预计会有多大的性能差异?
EDIT/UPDATE
总结答案和评论:
该系统被设计为可以工作几年,随着时间的推移添加的所有画廊仍然可以访问。这意味着存储需求非常巨大,旧相册的高分辨率图像将被移动到缓慢且廉价的专用存储设备上,因此建议不要使用所有缩略图的额外开销,这是一个严重的不可行选项。去年我需要存储超过 3TB 的图像(这只是高分辨率大小)。
我在使用 Lighttpd,我打算使用 rewrite-if-not-file
来获得现有缩略图的最佳性能。
我知道 I/O 写惩罚,我打算将它保持在最低限度,只在必要时写,最好是阅读。但是来自@N.B 的评论。实际上确实让我想到将低分辨率图像存储在 SSD 上,因此即使我需要创建它们并将它们写入磁盘,也比普通 HDD 具有更好的 I/O 性能。
实际上做一些测试会很困难(@Steve E.)我落后于计划,系统必须在本月底之前上线。 (我今天刚收到炸弹,他们正在拔掉旧系统的插头)。是的,灵活性是我想使用 SQL 的主要原因,但我预计 SQL 数据库会显着增长,除了文件信息外,还有大量我需要的其他信息存储、标记、购买、下载等,所以我也在努力确保我不会对 SQL 施加太大压力,而我实际上可以很好地利用其中的一些结构和文件系统访问。
您已经完成了困难的部分。 SQL 你的查询只会减慢你的速度...
这是你的做法
user--->php-->filesystem-->php--->user
如果 mysql 进来,事情就是这样
user--->php--->mysql--->filesystem--->mysql-->php--->user
所以您已经在不使用 mysql...
的情况下节省了一些时间
If somebody does access the gallery and the lowres version of the file doesn't exist on the server it is generated on the fly
如果高分辨率版本没有存储在数据库中而是作为服务器文件,这意味着低分辨率缩略图与高分辨率图像相比占据的比例很小space。例如,假设低分辨率图像的大小是高分辨率图像的 10%。在服务器上保留 所有 可用的低分辨率图像只会增加 10% 的存储需求,如果您没有 10% 的备用容量,那么您需要购买更多存储空间,不要尝试编程解决方法。
从评论来看,您似乎已经在数据库中存储了有关该文件的一些信息。如果是这种情况,那么您应该能够添加一个列以确定它是否空闲,并在查询其他信息的同时获得额外的列,几乎不会增加开销。
如果不进行测试,很难确定哪种方法会更快。简单的逻辑可能表明 PHP 访问磁盘更快,但这是基于许多假设。
在配置良好的系统中,经常需要的变量将在 RAM 缓存中而不是在磁盘上。这适用于文件系统的缓存以及 MySQL 缓存索引。缓存和其他机制的影响可能会产生与预期不同的结果。
在许多情况下,任何一种解决方案都可以工作并且足够,因为在设计良好的系统中,任何一种请求所花费的时间都应该是最少的,并且一种方法的额外性能可能不值得您使用 'FREE' 在文件名中。试用这两种方法并衡量性能并不会太难。
从长远来看,还要考虑 MySQL 为添加附加功能提供了更大的灵活性,如果所有状态都存储在文件名中,这些功能会变得复杂。
如果性能确实是一个重要问题,那么请考虑使用网络服务器检查磁盘上的文件(或在像 memcache 这样的缓存中)并 return 检查它是否存在,然后再将请求传递给 PHP 完全没有。 Nginx和Apache都可以做到这一点,这是一种常见的高流量网站加速方式。
我在服务器上存储了一些高分辨率文件(如果重要的话,100K+)并将它们组织在不同的画廊中。当有人访问画廊时,我只显示缩略图和图像的低分辨率版本,在某些情况下会加水印,而在其他情况下则不会。现在由于我说的是大量图片,画廊页面上显示的低分辨率版本在 X 天后从服务器中清除。如果有人确实访问了图库,并且服务器上不存在该文件的低分辨率版本,它会即时生成,但是当我生成低分辨率版本时,我可能需要为其添加水印或不添加水印。
目前,显示图像的脚本不执行任何 SQL 调用,它全部基于文件系统(如果文件存在等),是否为图像加水印的决定基于:
if (strpos($file_name,"FREE")===false){ //add watermark }else{ //just resize}
我的逻辑是,这比对文件名或文件 ID 进行 SQL 查询并检查它是否应该是无水印图像更高效。但是我觉得文件名中包含FREE这个词有点不方便。
如果我使用 SQL 查询而不是 strpos,我预计会有多大的性能差异?
EDIT/UPDATE
总结答案和评论:
该系统被设计为可以工作几年,随着时间的推移添加的所有画廊仍然可以访问。这意味着存储需求非常巨大,旧相册的高分辨率图像将被移动到缓慢且廉价的专用存储设备上,因此建议不要使用所有缩略图的额外开销,这是一个严重的不可行选项。去年我需要存储超过 3TB 的图像(这只是高分辨率大小)。
我在使用 Lighttpd,我打算使用
rewrite-if-not-file
来获得现有缩略图的最佳性能。我知道 I/O 写惩罚,我打算将它保持在最低限度,只在必要时写,最好是阅读。但是来自@N.B 的评论。实际上确实让我想到将低分辨率图像存储在 SSD 上,因此即使我需要创建它们并将它们写入磁盘,也比普通 HDD 具有更好的 I/O 性能。
实际上做一些测试会很困难(@Steve E.)我落后于计划,系统必须在本月底之前上线。 (我今天刚收到炸弹,他们正在拔掉旧系统的插头)。是的,灵活性是我想使用 SQL 的主要原因,但我预计 SQL 数据库会显着增长,除了文件信息外,还有大量我需要的其他信息存储、标记、购买、下载等,所以我也在努力确保我不会对 SQL 施加太大压力,而我实际上可以很好地利用其中的一些结构和文件系统访问。
您已经完成了困难的部分。 SQL 你的查询只会减慢你的速度...
这是你的做法
user--->php-->filesystem-->php--->user
如果 mysql 进来,事情就是这样
user--->php--->mysql--->filesystem--->mysql-->php--->user
所以您已经在不使用 mysql...
的情况下节省了一些时间If somebody does access the gallery and the lowres version of the file doesn't exist on the server it is generated on the fly
如果高分辨率版本没有存储在数据库中而是作为服务器文件,这意味着低分辨率缩略图与高分辨率图像相比占据的比例很小space。例如,假设低分辨率图像的大小是高分辨率图像的 10%。在服务器上保留 所有 可用的低分辨率图像只会增加 10% 的存储需求,如果您没有 10% 的备用容量,那么您需要购买更多存储空间,不要尝试编程解决方法。
从评论来看,您似乎已经在数据库中存储了有关该文件的一些信息。如果是这种情况,那么您应该能够添加一个列以确定它是否空闲,并在查询其他信息的同时获得额外的列,几乎不会增加开销。
如果不进行测试,很难确定哪种方法会更快。简单的逻辑可能表明 PHP 访问磁盘更快,但这是基于许多假设。
在配置良好的系统中,经常需要的变量将在 RAM 缓存中而不是在磁盘上。这适用于文件系统的缓存以及 MySQL 缓存索引。缓存和其他机制的影响可能会产生与预期不同的结果。
在许多情况下,任何一种解决方案都可以工作并且足够,因为在设计良好的系统中,任何一种请求所花费的时间都应该是最少的,并且一种方法的额外性能可能不值得您使用 'FREE' 在文件名中。试用这两种方法并衡量性能并不会太难。
从长远来看,还要考虑 MySQL 为添加附加功能提供了更大的灵活性,如果所有状态都存储在文件名中,这些功能会变得复杂。
如果性能确实是一个重要问题,那么请考虑使用网络服务器检查磁盘上的文件(或在像 memcache 这样的缓存中)并 return 检查它是否存在,然后再将请求传递给 PHP 完全没有。 Nginx和Apache都可以做到这一点,这是一种常见的高流量网站加速方式。