2009-10-07 6 views
4

Ma structure de table:CakePHP requêtes de base de données inefficaces: peuvent-elles être évitées?

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

je regardais les journaux SQL pour l'action "supprimer case", et je suis un peu horrifié.

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 

Ceci est peut-être le moyen le moins efficace de supprimer de ces tables que je pourrais concevoir. Je veux dire, il pourrait être remplacé par ceci:

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

Y at-il une raison pour laquelle Cake le fait de cette façon? Si non, savez-vous de quelque façon que je peux rationaliser la procédure sans casser les bibliothèques de base?


est ici les bits correspondants du code:

// 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

Je suppose que vous utilisez une forme d'ORM? – alex

+0

Si vous êtes, CakePHP expose-t-il une bibliothèque de base de données que vous pouvez utiliser vous-même? – alex

+0

Oui, Cake a son propre système ORM, mais je crois que les instructions sont générées à un niveau supérieur - c'est-à-dire que le code Cake demande au DBO de générer les 50 commandes. Cela a-t-il du sens? – nickf

Répondre

3

Si vous avez une relation hasMany, que je suppose est le cas que vous pourriez vouloir essayer de régler la « exclusive "drapeau:

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

exclusif: Quand est réglé sur true, la suppression récursive du modèle exclusif effectue la suppression d'un deleteAll(), au lieu de supprimer chaque sépara entité tely. Cela améliore grandement les performances, mais peut ne pas être idéal pour toutes les circonstances.

2

Malheureusement, ce gâteau est ainsi fait.

Vous pouvez remplacer la méthode del() dans votre modèle avec quelque chose comme ça mockup rude:

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

l'appel à parent :: del (...) à la fin de la méthode. Que fait-il exactement? – cardflopper

+1

@smchacko: Elle appelle la méthode 'del()' d'origine de la classe parente, la classe dont le modèle hérite et qui est 'del()' qu'elle surcharge. Lisez à propos de l'héritage de l'objet: http://php.net/manual/en/language.oop5.inheritance.php et du mot-clé 'parent': http://php.net/keyword.parent – deceze

+0

Et pourquoi devriez-vous appeler le parent? :: del() à nouveau, si vous essayez d'éviter les requêtes SQL inefficaces qu'il génère? – nanoman

Questions connexes