2010-05-30 94 views
0

我有一个MySQL表超过400万的数据;还有的问题是,一些查询工作,有的没有这取决于搜索词,当检索词有数据的比我得到以下错误的桌上有一大音量:巨大的MySQL表与Zend框架

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 

我现在有启用了元数据的Zend Framework缓存,我从该表的所有字段都有索引。该站点运行在具有2gb ram的专用服务器上。我还设置了内存限制:ini_set(“memory_limit”,“1000M”);

我可以优化的其他任何东西?

这些是我目前使用的查询类型:

  $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');   
     } 

和其他几个,但都是大同小异的。

问候

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

您不应该在表中的每一列都需要一个索引,您是否尝试过对生成的查询进行EXPLAIN? – robjmills 2010-05-30 21:14:44

+0

我也添加了EXPLIAN测试结果,你能帮助我改进吗? – Uffo 2010-05-31 11:17:05

回答

7

你真的需要一次加载所有的记录?我建议你在这些查询中使用LIMIT。如果您需要提供数据,请考虑使用Zend_Paginator

UPDATE:你正在采取的方法是通过Zend_Paginator所有的结果,这是过度使用大结果集。在这些情况下,更优化的方法是仅传递查询,然后它将负责仅提取显示页面所需的数据(这包括计算记录数并将查询限制为每个结果的数量页),例如:

$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

分页,他需要运行一个查询返回总结果集的大小 – robjmills 2010-05-30 21:19:19

+0

正确,这已经在Zend_Paginator组件中实现。 – nuqqsa 2010-05-30 21:24:21

+0

特别注意:该问题是由于尝试将所有数据加载到对象中造成的。这非常耗费资源,因此应该通过限制负载来进行优化,即限制获取结果的数量。分页需要首先计算总数结果,因此它包含2个查询,但是加载的数据量可能会急剧下降。 – nuqqsa 2010-05-30 21:33:39

0

Zend的分页程序是内存详尽外的开箱,因为它是。我必须将默认的memory_limit x4增加到512M,并且这个测试数据库不像实时版本那么大。