2009-08-14 5 views
2

Je crée un site web en utilisant php, mysql et zend framework. Lorsque j'essaie d'exécuter une requête sql, la génération de page saute à environ 0,5 seconde. C'est trop élevé. Si je tourne de sql, la génération de page est 0.001. La quantité de requêtes que j'exécute n'affecte pas vraiment le temps de génération de la page (1 à 10 requêtes testées). Reste à 0,5 seconde Je n'arrive pas à comprendre ce que je fais de mal.Zend Framework et Mysql - très lent

je me connecter à SQL bootstrap:

protected function _initDatabase() 
{ 
    try 
    { 
     $config = new Zend_Config_Ini(APPLICATION_PATH . '/configs/application.ini', APPLICATION_ENV); 
     $db = Zend_Db::factory($config -> database); 
     Zend_DB_Table_Abstract::setDefaultAdapter($db); 
    } 
    catch (Zend_Db_Exception $e) 
    { 

    } 
} 

, j'ai un modèle simple

class StandardAccessory extends Zend_DB_Table_Abstract 
{ 
    /** 
    * The default table name 
    */ 
    protected $_name = 'standard_accessory'; 

    protected $_primary = 'model'; 

    protected $_sequence = false; 
} 

Et enfin, dans mon contrôleur d'index, je lance simplement la méthode de recherche.

require_once APPLICATION_PATH . '/models/StandardAccessory.php'; 
    $sa = new StandardAccessory(); 
    $stndacc = $sa->find('abc'); 

Tout cela prend ~ 0,5 seconde, ce qui est beaucoup trop long. Aucune suggestion?

Merci!

Répondre

5

Conseils:

  • Cache the table metadata. Par défaut, Zend_Db_Table essaie de découvrir les métadonnées de la table chaque fois que votre objet table est instancié. Utilisez un cache pour réduire le nombre de fois qu'il doit faire cela. Ou bien coder en dur dans votre classe Table (note: les tables db ne sont pas des modèles).

  • Utilisez EXPLAIN pour analyser le plan d'optimisation de MySQL. Utilise-t-il un indice de manière efficace?

    mysql> EXPLAIN SELECT * FROM standard_accessory WHERE model = 'abc'; 
    
  • Utilisez BENCHMARK() pour mesurer la vitesse de la requête, ne pas utiliser PHP. La sous-requête doit renvoyer une seule colonne. Veillez donc à renvoyer une colonne non indexée afin que la requête touche les données au lieu de simplement renvoyer une entrée d'index.

    mysql> SELECT BENCHMARK(1000, 
        (SELECT nonindexed_column FROM standard_accessory WHERE model = 'abc')); 
    
  • Notez que Zend_Db_Adapter paresseux charges sa connexion db lorsque vous effectuez la première requête. Donc, s'il y a une lenteur à se connecter au serveur MySQL, cela se produira lorsque vous instanciez l'objet Table (lorsqu'il interroge les métadonnées). Une raison pour laquelle cela pourrait prendre beaucoup de temps? DNS lookups, peut-être?

+0

Et la question pour BENCHMARK devrait retourner 1 rangée, autrement mysql se plaignent: ERREUR 1242 (21000): La sous-requête renvoie plus de 1 rangée. –

+0

@Leonel Martins: Bon, je suppose que le PO utilise 'find()' qu'il restreint à la clé primaire de la table. Il devrait donc être garanti de renvoyer une seule ligne (ou zéro rangée, si 'abc' n'est pas trouvé). –

+0

Le premier lien sur la mise en cache des métadonnées est maintenant invalide, je suppose que c'était le suivant: https://framework.zend.com/manual/1.10/fr/zend.db.table.html#zend.db.table. metadata.caching –

0

En plus des suggestions ci-dessus j'ai fait un test très non scientifique et a constaté que l'adaptateur PDO était plus rapide pour moi dans ma demande (je sais mysqli est censé être plus rapide, mais peut-être est l'abstraction ZF). Je montre les résultats here (les temps indiqués sont seulement bons pour la comparaison)