2009-10-07 25 views
4

我的表結構:CakePHP低效的數據庫查詢:它們可以被避免嗎?

boxes (id, boxname) 
boxes_items (id, box_id, item_id) 

我一直在尋找的「刪除盒子」行動的SQL日誌,我稍微震驚。

SELECT COUNT(*) AS count FROM boxes Box WHERE Box.id = 191 
SELECT BoxesItem.id FROM boxes_items BoxesItem WHERE BoxesItem.box_id = 191 
SELECT COUNT(*) AS count FROM boxes_items BoxesItem WHERE BoxesItem.id = 1685 
DELETE FROM boxes_items WHERE boxes_items.id = 1685 
SELECT COUNT(*) AS count FROM boxes_items BoxesItem WHERE BoxesItem.id = 1686 
DELETE FROM boxes_items WHERE boxes_items.id = 1686 

    -- snip 50 more SELECT & DELETE statements -- 

SELECT COUNT(*) AS count FROM boxes_items BoxesItem WHERE BoxesItem.id = 1733 
DELETE FROM boxes_items WHERE boxes_items.id = 1733 

DELETE FROM boxes WHERE boxes.id = 191 

這可能是從這些表中刪除我可以想象的最不高效率的方式。我的意思是,它可以用這個替換:

DELETE FROM boxes WHERE id = 191 
DELETE FROM boxes_items WHERE box_id = 191 

Cake是否有這樣做的原因?如果沒有,您是否知道我可以簡化程序而不破壞核心庫的任何方式?


這裏的代碼的相關位:

// app/controllers/boxes_controller.php ///////////// 

public function delete($id = null) { 
    if ($this->Box->del($id)) { 
     $this->redirect(array('action'=>'index')); 
    } 
} 

// app/models/box.php /////////////////////////////// 

class Boxes extends AppModel { 
    var $hasAndBelongsToMany = array(
     'Item' 
    ); 
} 

// app/models/app_model.php ///////////////////////// 

class AppModel { 
    var $actsAs = array('Containable'); 
    var $recursive = -1; 
} 
+0

我假設你使用ORM的一種形式? – alex 2009-10-08 02:31:04

+0

如果是的話,CakePHP是否公開了一個數據庫庫,您可以使用它? – alex 2009-10-08 02:31:57

+0

是的,Cake有它自己的(?)ORM系統,但我相信這些語句是在更高級別生成的 - 也就是說,Cake代碼告訴DBO生成50個左右的命令。那有意義嗎? – nickf 2009-10-08 02:49:18

回答

3

如果你有一個的hasMany關係,這我假設的情況下,你可能想嘗試設置「獨家「標誌:

http://book.cakephp.org/view/82/hasMany

獨家:當exclusive設置爲true,遞歸模型刪除並用可以用deleteAll()調用刪除,而不是刪除每個實體separa, tely。這大大提高了性能,但可能不適合所有情況。

2

不幸的是這蛋糕是怎麼做的。

你可以用這樣的粗糙小樣覆蓋del()方法在你的模型:

function del($id, $cascade = true) { 
    if ($cascade) { 
     $this->BoxesItem->deleteAll(array('BoxesItem.box_id' => $id)); 
    } 
    return parent::del($id, false); 
} 
+0

在方法結束時調用parent :: del(...)。它究竟做了什麼? – cardflopper 2009-10-08 20:27:41

+1

@smchacko:它調用父類的原始'del()'方法,模型繼承的類以及del()它是否覆蓋。閱讀關於對象繼承:http://php.net/manual/en/language.oop5.inheritance.php和「父母」關鍵字:http://php.net/keyword.parent – deceze 2009-10-08 23:51:11

+0

爲什麼你應該打電話給父母:: del()再次,如果你想避免它生成的低效的SQL查詢? – nanoman 2009-10-10 07:56:34

相關問題