【发布时间】: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 语句之前正确转义。当你做出这样的假设时,你最终会给自己带来非常严重的麻烦。
标签: php mysql performance query-optimization