2010-02-09 42 views
14

我只是在Zend中设置了FirePHP,并且我注意到大量的DESCRIBE查询。某些页面在同一张表上有50个或更多相同的查询。例如Zend Framework中有大量的DESCRIBE查询

0.00198  connect  NULL 
0.00449 DESCRIBE `nodes` NULL 
0.00041 SELECT `nodes`.* FROM `nodes` WHERE (((`nodes`.`id` = 111))) NULL 
0.0037 DESCRIBE `nodes` NULL 
0.00155 SELECT `nodes`.* FROM `nodes` WHERE (((`nodes`.`id` = 111))) NULL 
0.00059 SELECT `nodes`.* FROM `nodes` WHERE (parent_id = '111') ORDER BY `order` ASC, `id` ASC NULL 
0.00366 DESCRIBE `nodes` NULL 
0.0054 DESCRIBE `nodes` NULL 
0.0049 DESCRIBE `nodes` NULL 
0.00519 DESCRIBE `nodes` NULL 
0.00492 DESCRIBE `nodes` NULL 
0.00691 DESCRIBE `nodes` NULL 
0.00741 DESCRIBE `nodes` NULL 
0.0048 DESCRIBE `nodes` NULL 
0.00556 DESCRIBE `nodes` NULL 
0.00516 DESCRIBE `nodes` NULL 
0.00487 DESCRIBE `nodes` NULL

...然后继续。

是由框架生成的所有这些DESCRIBE查询(我使用Zend_DbTable)?他们都是必需的吗?我应该担心它们还是不会影响性能?

回答

13

这些查询由执行的Zend_Db_Table以检测表的架构。您可以要求Zend_Db_Table使用Zend_Cache缓存结果以防止连续调用,但如果更改模式,请牢记这一点。

您可以通过这样做:

Zend_Db_Table_Abstract::setDefaultMetadataCache($cache); 
+0

我对此感兴趣。你知道设置$ cache部分的好资源吗? – Sonny 2010-02-09 20:56:54

+0

查看Zend框架手册:http://framework.zend.com/manual/en/zend.db.table.html#zend.db.table.metadata.caching – Johnco 2010-02-09 21:48:59

+0

我读过。我正在寻找有关不同设置的优缺点的建议,例如使用什么缓存类型,使用“文件”类型时要使用的目录等。 – Sonny 2010-02-10 16:44:04

3

Zend_Db_Adapter_Abstract::describeTable()在使用时执行这些查询以获取表格的元数据Zend_Db_Table这用于您未明确指定主键的情况。您可以启用MetaData缓存或仅使用Zend_Db而不是Zend_Db_Table

认为你不应该有这么多的描述查询。一旦设置了Zend_Db_Table实例,它将在第一次查询剩余请求后存储元数据。尝试使用Zend_Debugger或Xdebug来找出造成这种情况的原因。

参见

+0

这样做是每次都是建立Zend_Db_Table类的新实例。这就是为什么发生了这么多次。 – 2010-02-10 21:23:45

+0

@tomas是的,这就是为什么它困惑我,因为应该没有理由在一个请求中多次创建实例。 – Gordon 2010-02-10 21:50:02

+0

我正在为模型的每个实例实例化一个dbTable。我已经通过将dbTable实例作为模型的静态属性进行缓存来解决此问题。 – Tamlyn 2010-02-12 13:43:12

3

我用了一个单例模式的Zend_DbTable实例存储在我的基础模型类的静态数组。这将DB查询减少为每个请求对我来说足够好的一个请求,并且还减少了需要实例化的对象的数量。

例如:

protected $_dbTable; 
protected $_table; //override the database table name in subclass 

private static $_dbTableCache = array(); 

public function __construct() 
{ 
    $this->_dbTable = $this->getDbTableInstance($this->_table); 
} 

protected function getDbTableInstance($tableName) { 
    if (self::$_dbTableCache[$tableName] === null) { 
     self::$_dbTableCache[$tableName] = new Zend_Db_Table($tableName); 
    } 
    return self::$_dbTableCache[$tableName]; 
} 
+0

我正在做类似的事情,使用Zend_Registry。 – Sonny 2010-02-09 18:46:43

+1

注册表是更好的方式(更短的代码),我认为... :) – 2010-02-10 21:27:35

+0

为什么你有多个实例呢?我的意思是,对于多个表是的,但是你不需要同一个表的多个实例,是吗? – Gordon 2010-02-10 21:51:34