所以我有一个看起来像这样的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。
有什么方法可以重构我的查询,我的模型关系或其他东西,以便在相当少的调用中检索数据?
答案 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
));