CakePHP查询无明显原因地调用COUNT()两次

CakePHP查询无明显原因地调用COUNT()两次,php,mysql,cakephp,cakephp-model,Php,Mysql,Cakephp,Cakephp Model,注意:我最初在一小时前问了这个问题,但直到最近才意识到我犯了一个重大的复制粘贴错误。其中一个非常重要,删除旧帖子并重新开始更容易。很抱歉 在CakePHP框架中,在更新模型后,我转储了SQL查询计数(*)被调用两次,没有明显的原因 所以我有两种型号,$Foo和$Bar。为了简单起见,我没有定义任何$belongsTo或$hasnomy关系。这个问题只涉及$Foo,但以防万一,我还包括了$Bar代码 $data = array( 'something' => 12, 'som

注意:我最初在一小时前问了这个问题,但直到最近才意识到我犯了一个重大的复制粘贴错误。其中一个非常重要,删除旧帖子并重新开始更容易。很抱歉

在CakePHP框架中,在更新模型后,我转储了SQL查询<代码>计数(*)被调用两次,没有明显的原因

所以我有两种型号,
$Foo
$Bar
。为了简单起见,我没有定义任何
$belongsTo
$hasnomy
关系。这个问题只涉及$Foo,但以防万一,我还包括了$Bar代码

$data = array(
    'something' => 12,
    'something_else' => $this->Bar->field('id', $conditions),
);

$this->Foo->id = $this->Foo->field($data);
$this->Foo->save($data);
我根据一组条件(此处不相关)获取
$Bar.id
字段。我使用该id来确定应该插入或更新到
$Foo
中的
$data
。如果
$Foo
具有满足
$data
要求的id,则将返回该值;如果不为false,则返回。根据CakePHP的体系结构,
save()
将在有有效id时更新;否则它将插入。我很确定我没有做任何不寻常的事

以下是我在SQL转储中看到的内容:

从'foos'中选择'Foo'。'id'作为'Foo',其中'something`=12和'something\u else`=1限制1
选择COUNT(*)作为'COUNT',从'foos'中选择'Foo',其中'Foo`.'id`=1
选择COUNT(*)作为'COUNT',从'foos'中选择'Foo',其中'Foo`.'id`=1
更新`foos`SET`something`=12,something\u else`=1,其中`foos`.`id`=1'

就我的一生而言,我无法理解为什么需要
COUNT()
,更不用说为什么要调用两次了。有人知道发生了什么吗?谢谢您的帮助。

无法告诉您发生了什么(因为我认为没有足够的代码),但可以为您提供一个解决方法

使用“在重复键更新字段=值,字段2=值2上插入表(id,字段,字段2)值(id,值,值2)”语法执行查询


这使SQL能够检查重复项,并且还将清除检查行是否存在和尝试插入之间的几秒钟(以防在检查后插入另一个进程)。为此,字段“id”必须是主键或“unique”索引,以便它知道如何触发更新。

我没有使用过CakePHP,但是查看源代码,您将在字段函数中看到它调用find方法

所以这个电话,

$data = array(
    'something' => 12,
    'something_else' => $this->Bar->field('id', $conditions),
);
生成:

SELECT `Foo`.`id` FROM `foos` AS `Foo` WHERE `something` = 12 AND `something_else` = 1     LIMIT 1
然后设置字段调用

$this->Foo->id = $this->Foo->field($data);
通过内部查找函数调用生成:

SELECT COUNT(*) AS `count` FROM `foos` AS `Foo` WHERE `Foo`.`id` = 1
Save函数还调用find以查看保存前记录是否存在,这将生成第二个调用:

SELECT COUNT(*) AS `count` FROM `foos` AS `Foo` WHERE `Foo`.`id` = 1
最后一个查询是显而易见的save本身


请自己验证我是否正确阅读了它,但它似乎就是这样做的。

我相信这是正确的答案。非常感谢瑞秋!所以这仅仅是CakePHP的故意行为吗?Alvaro,在四年前写这篇文章的时候,它看起来是故意的,尽管从那以后我就没有看过代码了。可以选择修改行为,但这超出了我的专业范围。我同意Robbie的观点,我已经知道解决方法。我只是想了解CakePHP的包装器是如何工作的。谢谢