2011-07-06 45 views
2

所以我有一個蛋糕查詢看起來是這樣的:可以減少CakePHP正在製作的數據庫查詢數量嗎?

$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毫秒,但仍然看起來他們可能會加起來一些重要的東西,而這在特別煩人的時候如此之多q ueries是重複的 - 例如所有Releasetype.types是無論是900還是901

有沒有什麼辦法可以修改我的查詢,我的模型關係,還是其他什麼東西,這樣的數據是相當少的調用獲取的?

回答

0

蛋糕是做一個「主」查詢。在這種情況下,「發佈」模型會查找並找到每個在其中查找到的行,以獲取您在「包含」中指定的數據。

這是正常現象。

一個大問題,我看到的是你的陳述「這些查詢只服用< 200毫秒」。伊莫他們不應該超過1ms甚至0ms。您似乎需要正確地爲該表格編制索引。

我不是特別喜歡強迫蛋糕做的加入,彷彿它本來是一個加入蛋糕開發者將使它加入。

如果你真的想降低查詢次數,即使其不需要的,看一個)linkable behavior B)bindModel C)adhoc-joins

+0

$ cacheQueries也將減少對欺騙查詢。 – Dunhamzzz

+0

嗯,確實讓這些查詢變得非常快!我已經嘗試了一些基本的索引,但是我不得不承認我對於我需要做的事情感到有點失落。你能提出一些簡單有效的方法來索引這裏嗎? (另外,我剛剛讀了查詢時間離開最右邊的列上的SQL轉儲,因爲在我的例子,它並不真正需要20秒的頁面重新加載,但是這就是在SQL轉儲暗示總和查詢時間是,所以,我不知道!) – thesunneversets

-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 
)); 
+0

嗯,有趣的想法,什麼是其背後的原理是什麼?這似乎可能只是將條件轉移一點點,所以您在第一次查詢時可能失去的第二個查詢所獲得的結果是什麼?當然,我的第一次嘗試似乎並沒有產生任何顯着的速度增加... – thesunneversets

+0

,這將只是給錯誤的查詢不被上加入 – dogmatic69

+0

@ dogmatic69做,什麼樣的錯誤?我已經做了一些代碼片段(爲簡單起見,不包括ReleaseType表格),它工作正常,也許我失去了一些東西? https://gist.github.com/c0cb7aeac6a41e751f9e – andreyv

相關問題