我有一个用户模型和一个消息模型。
Message模型两次链接到User模型:
public $belongsTo = array(
'UserSender' => array(
'className' => 'User',
'foreignKey' => 'sender_id',
'counterCache' => array(
'messages_sent_count' => array(
'is_deleted' => FALSE
)
)
),
'UserRecipient' => array(
'className' => 'User',
'foreignKey' => 'recipient_id',
'counterCache' => array(
'messages_received_count' => array(
'is_deleted' => FALSE
),
'messages_unread_count' => array(
'is_deleted' => FALSE,
'is_read' => FALSE
)
)
),
'Operator' => array(
'className' => 'Operator',
'foreignKey' => 'operator_id'
)
);
除了User模型之外,Message模型还$属于Operator模型。运算符模型与用户的消息计数无关,但其表仍在计数查询中加入,如调试所示:
'query' => 'SELECT COUNT(*) AS `count` FROM `database`.`messages` AS `Message` LEFT JOIN `database`.`operators` AS `Operator` ON (`Message`.`operator_id` = `Operator`.`id`) LEFT JOIN `database`.`users` AS `UserSender` ON (`Message`.`sender_id` = `UserSender`.`id`) LEFT JOIN `database`.`users` AS `UserRecipient` ON (`Message`.`recipient_id` = `UserRecipient`.`id`) WHERE `Message`.`is_deleted` = '0' AND `Message`.`sender_id` = 389',
'params' => array(),
'affected' => (int) 1,
'numRows' => (int) 1,
'took' => (float) 394
为了简单起见,我实际上排除了另一个消息模型$ belongsTo的模型,但上面的查询显示了问题。
counterCache函数只是为了更新计数器而进行非常昂贵的查询。有没有办法可以覆盖或调整counterCache方法,以便不在查询中连接不相关的表?
答案 0 :(得分:3)
我现在无法对其进行测试,但由于the recursive
setting used by Model::updateCounterCache()
是基于是否为计数器缓存字段定义条件而进行硬编码的,因此唯一可以改变此方法(除了完全重新实现{{1} }}}可能会修改Model::updateCounterCache()
模型的count
或Model::_findCount()
中的Model::beforeFind()
查询。
Message
根据您实际需要的控制程度,containable行为也可能起作用,如果没有传递包含,它会将public function beforeFind($query) {
// ... figure whether this is the count query for updateCounterCache,
// maybe even try to analyze whether the passed conditions require
// joins or not.
if(/* ... */) {
$query['recursive'] = -1;
}
return $query;
}
设置为recursive
-1