将值计算从 SQL 移到 PHP 层会更好吗?
Posted
技术标签:
【中文标题】将值计算从 SQL 移到 PHP 层会更好吗?【英文标题】:Is it better to move values computation to PHP layer out of SQL? 【发布时间】:2012-08-23 02:01:47 【问题描述】:此方法用于在 User 和 TargetUser 之间选择操作数,例如只是在两个用户之间。这个方法的结果值依赖于GetTotalOfPossibleActions()
的动态返回值(每个用户都有自己的编号)。
问题:将值计算移到 SQL 之外的 php 层会更好吗?
public function GetAction()
// ...
$MaxActionCount = $this->GetTotalOfPossibleActions();
return registry::getInstance()->get('DB')->select(
'SELECT
`Action`
, `HA`.`Id` AS `ActionId`
, IF(`Count` IS NULL
, IF('.$MaxActionCount.' % 2
, IF(`HA`.`Id` = 1
, CEIL('.$MaxActionCount.' / 2)
, FLOOR('.$MaxActionCount.' / 2))
, '.$MaxActionCount.' / 2)
, GREATEST(IF('.$MaxActionCount.' % 2
, IF(`HA`.`Id` = 1
, CEIL('.$MaxActionCount.' / 2) - CONVERT(`H`.`Count`, SIGNED)
, FLOOR('.$MaxActionCount.' / 2) - CONVERT(`H`.`Count`, SIGNED))
, '.$MaxActionCount.' / 2 - `H`.`Count`), 0)
) AS `CountLeft`
FROM `Help` AS `H`
RIGHT JOIN `HelpAction` AS `HA`
ON `H`.`ActionId` = `HA`.`Id`
AND `UserId` = '.$this->UserId.'
AND `TargetUserId` = '.$this->TargetUserId.'
AND `CreatedDate` = CURDATE()'));
【问题讨论】:
您只是将变量猛烈撞击到 SQL 中的方式非常令人担忧。您至少应该使用占位符来避免 SQL 注入错误或更糟。 SQL 注入在这里是不可能的,因为 $MaxActionCount 是内部值。 @Roman 这甚至不是重点。如果您不使用参数化查询,则数据库引擎无法重用您的查询。每次使用它访问数据库时都必须完全解析它。将其转换为存储过程并将值作为参数发送。与将一些简单的数学运算从这里转移到那里相比,这将节省更多时间。 @Tomalak,这正是我今天早上想的,将其转换为 SP。 “参数化查询”是什么意思? 数据来自哪里并不重要。它必须在放入您的 SQL 语句之前正确转义。当你做出这样的假设时,你最终会给自己带来非常严重的麻烦。 【参考方案1】:没有硬性和快速的答案,但以下是我应用的一般指南。
PHP 服务器可以负载平衡和倍增。因此,如果您的 CPU 周期不足,您可以相对轻松地添加另一个 PHP 服务器。反之,mysql服务器也不能轻易成倍增加。您可以添加复制服务器并在从属服务器上运行复杂的“选择”,但是复制会增加一点压力,并且在主服务器上的更新与从服务器上可用之间总是存在延迟。 (永远不要相信说它是毫秒的数据库管理员;当服务器处于压力之下/有备份等时它会变慢。)
所以 +1 给 PHP。
但是,SQL 的构建和设计目的是对数据进行计算。这就是它的工作。它的效率要高得多(假设您正确设计了表、查询和索引)。
所以 +1 到 mySQL。
如果你在MySQL上做计算,你也不需要把整个数据表转给PHP来处理和处理。这样可以节省两者之间的网络流量。
所以 +1 到 mySQL。
但是,如果您难以正确查询,或者 MySQL 正在耗尽所有内存,不停地创建临时表并交换到硬盘,那么通过分解PHP中的计算。 MySQL EXPLAIN 和缓慢的查询日志有时令人沮丧。
所以 +1 给 PHP。
所以... 2 全部。如果您在一台服务器上同时拥有两者,并且查询没有给您带来问题,那么让 MySQL 来完成它的工作。如果您遇到查询问题,请退回到 PHP。如果您在多台服务器上,请尽可能多地使用 MySQL,而不会遇到瓶颈。如果 MySQL 是一个瓶颈并且无法复制,请退回到 PHP。然后检查网络流量。
然后记得在负载增加时重新评估...
【讨论】:
PHP 服务器在 AWS Auto Scaling 下,DB 是 Master / Slave + Slave Replica。我现在把它移到 SP,让我们看看......以上是关于将值计算从 SQL 移到 PHP 层会更好吗?的主要内容,如果未能解决你的问题,请参考以下文章