带有 Zend 框架的巨大 mysql 表
Posted
技术标签:
【中文标题】带有 Zend 框架的巨大 mysql 表【英文标题】:Huge mysql table with Zend Framework 【发布时间】:2010-05-30 21:06:14 【问题描述】:我有一个超过 400 万条数据的 mysql 表;问题是,有些查询可以工作,有些不可以,这取决于搜索词,如果搜索词在表中的数据量很大,我会收到以下错误:
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 内存的专用服务器上运行。
我还将内存限制设置为: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 代码
$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 解释结果
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
【问题讨论】:
您不应该对表中的每一列都使用索引,您是否尝试过对生成的查询进行解释? 我还添加了EXPLIAN测试结果,你能帮我改进一下吗? 【参考方案1】:您真的需要一次加载所有记录吗?我建议您在这些查询中使用 LIMIT 。如果您需要展示数据,也可以考虑使用Zend_Paginator。
更新:您采用的方法是将所有结果都传递给 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);
【讨论】:
要分页,他需要运行一个返回总结果集大小的查询 对,这已经在 Zend_Paginator 组件中实现了。 额外说明:问题是由于试图将所有数据加载到对象中引起的。这是非常消耗资源的,因此应该通过限制负载来进行优化,即限制获取结果的数量。分页需要先统计结果总数,因此它由 2 个查询组成,但加载的数据量可能会大大减少。 然后尝试限制您的最大限制并检查是否可以从选择语句中删除某些列。 //ZEND_PAGINATOR代码添加到主帖;我需要将 Zend_Paginator 设置为仅 X 页面所需的数据,现在正在一次加载所有数据....你知道如何将其添加到我的代码中吗?【参考方案2】:Zend 分页器是开箱即用的内存穷尽。我已经不得不将默认的 memory_limit x4 增加到 512M,而且测试数据库没有实际版本最终会那么大。
【讨论】:
以上是关于带有 Zend 框架的巨大 mysql 表的主要内容,如果未能解决你的问题,请参考以下文章
Zend 框架项目 - 日历:需要为每个用户分别提供带有事件的网络日历(如谷歌日历)
使用 Zend 框架的动态网站导航 - XML 与 MySQL