PHP 性能:每次点击时查询数据库?

Posted

技术标签:

【中文标题】PHP 性能:每次点击时查询数据库?【英文标题】:PHP Performance: Query to database on each hit? 【发布时间】:2011-12-07 11:41:44 【问题描述】:

我在数据库中有一个表 EVENTS。 (mysql) 当用户获取 URL www.example.com/today 服务器执行 php 语句和 SQL 查询到数据库时。

SELECT * FROM event WHERE DATE(date_end) >= DATE(NOW()) AND DATE(date_start) <= DATE(NOW())

问题:以这种方式制作是否值得,而我本可以每天制作一些包含新鲜事件及其数据的“准备好的”静态文件或表格?

还有一个问题:你会建议使用 Yii 吗?因为在我的本地主机上似乎有点慢。

【问题讨论】:

【参考方案1】:

Yii 支持caching(我个人从未使用过 Yii,因为我是 symfony 人,但这无关紧要)

您可以将缓存文件的到期时间设置为 6 小时。 6 小时后,当用户请求页面时,您的页面将使用数据库中的事件进行更新。

每个页面请求 1 次查询实际上没什么,即使您通过使用缓存可以获得轻微的性能提升,但仅针对 1 次查询真的不值得付出努力。

我有一个网站,在某些页面上必须执行多达 200 多个查询。我缓存了页面,以便每隔几分钟才调用一次数据库,以确保我不会在每个页面加载时都执行相同的查询。即5分钟后,当用户发出请求时,缓存文件已经过期,然后从数据库中加载新的内容。

您可以进行优化。例如,看看 YSlow。使用这个 Firefox 插件,您可以查看页面上的瓶颈在哪里。即许多背景图像?将其转换为精灵。不使用 CDN 加载 Jquery?然后使用 CDN。使用宽度和高度属性调整图像大小?实际调整图像大小等。

在 PHP 性能方面。看看APC,它是一个 PHP 加速器。当您的 PHP 应用程序变得复杂并且您正在执行大量代码时,您应该注意到显着的性能提升。但是,对于仅调用一个查询的简单页面,您可能不会注意到性能提升很多。

对于 mysql,利用索引。如果您正在使用事件名称列搜索事件,请确保您在此列上有索引。

对于框架,你可以使用你想要的。它们都可以进行优化以快速运行。选择权在你。

总结一下:

对于你正在做的事情。如果它只是页面上的一个查询,那么使用缓存和框架就没有多大意义了。如果您的应用程序确实变得复杂并且您开始使用大量查询,那么使用框架(代码分离、ORM、路由、表单验证等)并利用框架必须提供的缓存功能将是有益的。

【讨论】:

对执行 200 多个查询的页面进行缓存是否很好。但这不是治愈方法。您应该确定为什么它需要执行 200 多个查询。 PS:- 盲目地使缓存过期(每 5 分钟一次)不是明智之举。第一个用户点击页面(在 5 分钟间隔之后)会得到非常糟糕的响应。如果有多个并发用户访问同一个页面,由于缓存没有到位,他们将通过再次执行所有查询来相互竞争。 @ajreal 当我有 80-100 个表时,我将如何优化它?我需要有这么多的查询。不,有问题的页面是为每个用户缓存的。即他们有自己的缓存版本。请不要做假设。一些复杂的网络应用需要这么多查询。 真的吗?那么,当您不了解数据库的数据结构或 SQL 查询的性质时,您如何能够输入任何建议呢? 200 个查询并不多。许多复杂的网络应用程序使用的远不止这些(想想具有许多小部件的网络应用程序)。此外,由于其他优化,页面加载时间非常快。所有查询都经过分析,在许多情况下,它们已被重写。 OP 询问是否使用 YII 框架以及在 1 页上使用 1 个查询对性能的影响。【参考方案2】:

不要在查询中使用 NOW()。 NOW() 不能缓存到 mysql 查询缓存中。

文档:- http://dev.mysql.com/doc/refman/5.1/en/query-cache-operation.html

如果查询包含下表中显示的任何函数,则无法缓存该查询。 现在()

在左侧比较中始终使用常量。 在您的情况下,您执行从日期时间(或时间戳)到日期的类型转换, 这是一个坏习惯,考虑一下:-

$start_date = date('Y-m-d 00:00:00', time());
$end_date = date('Y-m-d 23:59:59', time());

DATE(date_end) >= DATE(NOW()) AND DATE(date_start) <= DATE(NOW())
==>
date_end between $start_date and $end_date
and
date_start <= $end_date

更重要的是,在 date_start 和 date_end 上构建复合索引 if where 子句总是需要比较两列

将所有内容存储在静态中很好, 但是当有更新时,它需要更多的努力来使缓存过期/失效。

是否使用 Yii 是次要考虑,先解决明显的问题 (这是昂贵的 mysql 查询)。

【讨论】:

以上是关于PHP 性能:每次点击时查询数据库?的主要内容,如果未能解决你的问题,请参考以下文章

PHP 从HTML选择标签发布查询

Redis

如何使用 useLazyQuery() 在每次点击时执行查询

php实现查询数据库数据,每次限定1000条

php+mysql预查询prepare 与普通查询的性能对比

如何在使用 PHP-PDO 记录查询时获取最后一个插入 ID