我可以减少CakePHP在这里制作的数据库查询数量吗?

时间:2011-07-06 00:26:24

标签: mysql cakephp

所以我有一个看起来像这样的Cake查询:

$forthcomingReleases = $this->Release->find('all', array(
        'contain'=>array('Artist.name', 'Artist.slug', 'Releasetype.type', 'Format.Mediatype.name'),
        'conditions'=>array('release_date >' => date('Ymd'), 'Release.is_deleted' => false),                
        'order'=>array('release_date DESC'),
        'limit'=>10
    ));

我在SQL转储中看到的是这样的事情:

45  SELECT `Artist`.`name`, `Artist`.`slug` FROM `artists` AS `Artist` WHERE `Artist`.`id` = 10021      1   1   167
46  SELECT `Artist`.`name`, `Artist`.`slug` FROM `artists` AS `Artist` WHERE `Artist`.`id` = 10159      1   1   168
47  SELECT `Artist`.`name`, `Artist`.`slug` FROM `artists` AS `Artist` WHERE `Artist`.`id` = 10021      1   1   170
48  SELECT `Artist`.`name`, `Artist`.`slug` FROM `artists` AS `Artist` WHERE `Artist`.`id` = 10159      1   1   168
49  SELECT `Artist`.`name`, `Artist`.`slug` FROM `artists` AS `Artist` WHERE `Artist`.`id` = 1338       1   1   169
50  SELECT `Artist`.`name`, `Artist`.`slug` FROM `artists` AS `Artist` WHERE `Artist`.`id` = 10159      1   1   187
51  SELECT `Artist`.`name`, `Artist`.`slug` FROM `artists` AS `Artist` WHERE `Artist`.`id` = 569        1   1   211
52  SELECT `Artist`.`name`, `Artist`.`slug` FROM `artists` AS `Artist` WHERE `Artist`.`id` = 569        1   1   168
53  SELECT `Artist`.`name`, `Artist`.`slug` FROM `artists` AS `Artist` WHERE `Artist`.`id` = 10451      1   1   182
54  SELECT `Releasetype`.`type` FROM `releasetypes` AS `Releasetype` WHERE `Releasetype`.`id` = 901         1   1   170
55  SELECT `Releasetype`.`type` FROM `releasetypes` AS `Releasetype` WHERE `Releasetype`.`id` = 901         1   1   171
56  SELECT `Releasetype`.`type` FROM `releasetypes` AS `Releasetype` WHERE `Releasetype`.`id` = 901         1   1   180 
57  SELECT `Releasetype`.`type` FROM `releasetypes` AS `Releasetype` WHERE `Releasetype`.`id` = 900         1   1   171
58  SELECT `Releasetype`.`type` FROM `releasetypes` AS `Releasetype` WHERE `Releasetype`.`id` = 900         1   1   183
59  SELECT `Releasetype`.`type` FROM `releasetypes` AS `Releasetype` WHERE `Releasetype`.`id` = 901         1   1   171
60  SELECT `Releasetype`.`type` FROM `releasetypes` AS `Releasetype` WHERE `Releasetype`.`id` = 901 

(这只是一个用于说明目的的摘录,还有更多的查询。)

即使这些查询中的每一个只花费<200毫秒,它们似乎仍然可能会增加一些重要的东西,当这么多的查询是重复的时候,这尤其令人讨厌 - 例如所有Releasetype.types都是900或901。

有什么方法可以重构我的查询,我的模型关系或其他东西,以便在相当少的调用中检索数据?

2 个答案:

答案 0 :(得分:0)

Cake正在做一个'主'查询。在这种情况下,“发布”模型查找,并且对于在那里找到的每一行,它执行查询以获取您在“包含”中指定的数据。

这是预期的行为。

我看到的一个大问题是你的陈述'这些查询只花了<200毫秒'。 Imo他们不应该超过1ms甚至0ms。看起来你需要正确索引该表。

我并不是特别喜欢强迫蛋糕做加入,好像它本来是一个加入蛋糕开发者会让它加入。

如果你真的想降低查询次数,即使它不需要,请查看a)linkable behavior b)bindModel c)adhoc-joins

答案 1 :(得分:-1)

作为替代方案,您可以将查询重新排列为以下内容:

$releaseList = $this->Release->find('list', array(
     'conditions' => array(
        'release_date > ' => date('Ymd'), 
        'Release.is_deleted' => false
     ),
     'fields' => array('id','id')

));
$releaseIds = array_keys($releaseList);

//now the actual query you used, searching by ids should execute faster
$forthcomingReleases = $this->Release->find('all', array(
   'conditions' => array('Release.id' => $releaseIds),
   'contain'    => array('Artist.name', 'Artist.slug', 'Releasetype.type', 'Format.Mediatype.name'),
    'order'     => array('release_date DESC'),
    'limit'     => 10 
));