2010-05-30 7 views
0

J'ai une table mysql avec plus de 4 millions de données; Eh bien, le problème est que certaines requêtes fonctionnent et d'autres pas dépend du terme de recherche, si le terme de recherche a un grand volume de données dans le tableau que je reçois l'erreur suivante:Grande table mysql avec Zend Framework

Fatal error: Allowed memory size of 1048576000 bytes exhausted (tried to allocate 75 bytes) in /home/****/public_html/Zend/Db/Statement/Pdo.php on line 290 

J'ai actuellement Zend Framework cache pour les métadonnées activées, j'ai un index sur tous les champs de cette table. Le site est en cours d'exécution sur un serveur dédié avec 2 Go de RAM.

J'ai également défini la limite de mémoire sur: ini_set ("memory_limit", "1000M");

D'autres choses que je peux optimiser?

Ce sont les types de requête que je suis actuellement en utilisant:

  $do = $this->select() 
       ->where('branche LIKE ?','%'.mysql_escape_string($branche).'%') 
       ->order('premium DESC'); 

     } 


     //For name 
     if(empty($branche) && empty($plz)) 
     { 
       $do = $this->select("MATCH(`name`) AGAINST ('{$theString}') AS score") 
       ->where('MATCH(`name`) AGAINST(? IN BOOLEAN MODE)', $theString) 
       ->order('premium DESC, score');   
     } 

et quelques autres, mais ils sont à peu près les mêmes.

Cordialement

// LE

Zend_Paginator CODE

 $d = $firmen->doSearch($finalType,$theKeyword,$thePLZ,$theBranche,false,false,false,$theOrder); 
    if ($d !== false) { 
     $paginator = Zend_Paginator::factory($d); 
     $paginator->setItemCountPerPage(5) 
        ->setPageRange(10) 
        ->setCurrentPageNumber($pag); 

     $this->view->data = $paginator; 

// MYSQL résultats EXPLAIN

mysql> EXPLAIN select * from `wirtscha_ksw`.`firmen` WHERE `name` LIKE '%gmbh%';ERROR 2006 (HY000): MySQL server has gone away 
No connection. Trying to reconnect... 
Connection id: 32911 
Current database: *** NONE *** 

+----+-------------+--------+------+---------------+------+---------+------+---------+-------------+ 
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra  | 
+----+-------------+--------+------+---------------+------+---------+------+---------+-------------+ 
| 1 | SIMPLE  | firmen | ALL | NULL   | NULL | NULL | NULL | 3749155 | Using where | 
+----+-------------+--------+------+---------------+------+---------+------+---------+- ------------+ 
1 row in set (0.03 sec 
+0

vous ne devriez pas avoir besoin d'un index sur chaque colonne de la table, avez-vous essayé un EXPLAIN sur la requête générée? – robjmills

+0

J'ai également ajouté les résultats des tests EXPLIAN, pouvez-vous m'aider à améliorer? – Uffo

Répondre

7

Avez-vous vraiment besoin de charger tous les enregistrements à la fois? Je vous recommande d'utiliser LIMIT dans ces requêtes. Dans le cas où vous avez besoin de présenter les données, pensez également à utiliser Zend_Paginator.

MISE À JOUR: L'approche que vous prenez est de passer Zend_Paginator tous les résultats, ce qui est exagéré avec de grands résultats. Une approche plus optimale dans ces cas est de passer juste la requête, et il prendra alors soin de récupérer seulement les données qui sont nécessaires pour afficher la page (cela inclut le nombre d'enregistrements et en limitant la requête au nombre de résultats par la page), par exemple:

$paginator = new Zend_Paginator(
    // $query is an instance of Zend_Db_Select 
    new Zend_Paginator_Adapter_DbSelect($query); 
); 
$paginator->setItemCountPerPage(5) 
      ->setPageRange(10) 
      ->setCurrentPageNumber($pag); 
+0

pour paginer il aurait besoin d'exécuter une requête qui renvoie la taille du total resultset – robjmills

+0

Right, et cela est déjà implémenté dans le composant Zend_Paginator. – nuqqsa

+0

Remarque supplémentaire: le problème est dû à la tentative de chargement de TOUTES les données dans des objets. Ceci consomme beaucoup de ressources, donc l'optimisation doit être faite en limitant la charge, c'est-à-dire en limitant le nombre de résultats récupérés. Une pagination nécessite d'abord compter les résultats du nombre total, donc il se compose de 2 requêtes, mais la quantité de données chargées peut diminuer considérablement. – nuqqsa

0

Zend paginator est une mémoire exhaustive out-of-the-box tel qu'il est. J'ai dû augmenter le memory_limit x4 à 512M par défaut déjà et c'est avec une base de données de test qui n'est pas aussi grande que la version en direct sera finalement.