php - Yii 关系在查询中生成 GROUP BY 子句

标签 php mysql sql yii

我有 User、Play 和 UserPlay 模型。这是用户模型中定义的关系,用于计算用户玩游戏的总时间。

'playedhours'=>array(self::STAT, 'Play', 'UserPlay(user_id,play_id)', 
'select'=>'SUM(duration)'),

现在我正在尝试使用用户 ID 查找持续时间总和。

$playedHours = User::model()->findByPk($model->user_id)->playedhours)/3600;

在大量数据上执行此关系需要很长时间。然后查看该关系生成的查询。

SELECT SUM(duration) AS `s`, `UserPlay`.`user_id` AS `c0` FROM `Play` `t` INNER JOIN    
`UserPlay` ON (`t`.`id`=`UserPlay`.`play_id`) GROUP BY `UserPlay`.`user_id` HAVING    
(`UserPlay`.`user_id`=9);

UserPlay.user_id 上的 GROUP BY 需要很长时间。因为我在这里不需要 Group by 子句。

我的问题是,如何避免上述关系中的 GROUP BY 子句。

最佳答案

STAT 关系根据定义是聚合查询,请参阅 Statistical Query 。 您无法在此处删除 GROUP BY 并对聚合数据进行有意义的查询。 SUM()、AVG() 等都是聚合函数,请参见 GROUP BY Functions ,查看 MYSQL 支持的所有聚合函数的列表。

您的问题在于您正在执行 HAVING 子句的计算。这不是必需的,因为 HAVING 在聚合发生后检查条件,您可以使用它来放置条件,例如 SUM(duration) > 500

基本上发生的情况是,您首先将所有用户单独分组,然后过滤您想要的用户 ID。如果您使用 WHERE 子句来过滤 before 而不是 after,则聚合仅针对您想要的用户,然后对其进行分组,您的查询会更快。

Although Active Record is good at modelling data in an OOP fashion, it actually degrades performance due to the fact that it needs to create one or several objects to represent each row of query result. For data intensive applications, using DAO or database APIs at lower level could be a better choice

因此,最好使用 CommandBuilder 或 DAO API 更改与直接查询数据库的模型函数的关系。像这样的事情

Class User extends CActiveRecord {

....
    public function getPlayedhours(){
        if(!isset($this->id)) // to prevent query running on a newly created object without a row loaded to it
            return 0;
        $played = Yii::app()->db->createCommand()
               ->select('SUM(duration)')
               ->from('play')
               ->join("user_play up","up.play_id = play.id")
               ->where("up.user_id =".$this->id)
               ->group("up.user_id")
               ->queryScalar();
        if($played == null)
           return 0;
        else 
          return $played/3600 ; 
       }
....
}

如果查询仍然很慢,请尝试优化索引,实现缓存机制,并使用解释命令找出实际上什么花费了更多时间,更重要的是为什么。如果什么都不够好,请升级您的硬件。

关于php - Yii 关系在查询中生成 GROUP BY 子句,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24773935/

相关文章:

mysql 查询每行的另一个表的 max()

c# - 注册后将用户详细信息输入数据库

php - 如何在 php 中创建确认是/否?

javascript - 如何调用ajax函数直到已经运行ajax不给出响应?

php - Mysql 查询需要一对多关系来进行匹配搜索

php - 将 PHP 代码从 MSSQL 迁移到 MySQL

mysql - 在 MYSQL 中,如何获得 LEFT JOIN 返回一个表中的每一行,以及如果另一个表中存在任何匹配行则返回一个标志?

php - Symfony2 创建和下载 zip 文件

php - 如何在 Swift 的 URLSession 请求中添加 POST 参数

Mysql数据库设计一个复杂的购物目录部分