2010-02-09 41 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