2012-05-10 42 views
1

在對一個相當大的應用程序(350個表db,某些表上的幾百萬個條目)中實現的不同庫/框架進行了一些研究後,我發現Zend_Db很容易完成我想要做的事情:適配器管理數據庫之間快速切換。Zend_Db性能

的問題是,表演也相當低廉,這裏有一個例子($ DB是一個基本適配器,時間計算上的選擇/只取):

SQL查詢(用於查詢進行檢測,該表包含〜200種元素)

SELECT * FROM element WHERE id=2' 

基本PDO - 0.6392s

$db = new PDO('mysql:dbname=etab_191;host=127.0.0.1', 'root'); 
for ($i=0; $i<2000; $i++) { 
    $stmt = $db->query($sql); 
    $p = $stmt->fetch(PDO::FETCH_OBJ); 
    $stmt->closeCursor(); 
} 

當前的應用程序的數據庫管理器 - 0.7401s(超過mysqli的核心功能簡單抽象層)

$db = GestionConnexionBDD::getInstance('default', 1)->gestionBDD; 
for ($i=0; $i<2000; $i++) { 
    $res = $db->query($sql); 
    $p = $db->fetchObject($res); 
    $db->freeResult($res); 
} 

Zend_Db的手動查詢 - 1.0647s(Mv_Core_Db_Manager是基於Zend的一個抽象層,返回的列表一個Zend_Db_Adapter_Abstract)

$db = Mv_Core_Db_Manager::getInstance()->getAdapter('default', 1); 
for ($i=0; $i<2000; $i++) { 
    $stmt = $db->query($sql); 
    $p = $stmt->fetch(); 
    $stmt->closeCursor(); 
} 

Zend_Db_Table_Abstract查詢 - 3.6702s(扭捏與Zend_Db_Table_Abstrac T :: setDefaultMetadataCache($緩存))

$elmt = new Element(); 
for ($i=0; $i<2000; $i++) { 
    $elmt->find(2); 
} 

查詢環路上殺死zend的表演。我知道這不是最好的事情,但是應用程序已經開發出來了,我很樂意改變可能的代碼。

有些想法?難道我做錯了什麼 ?

+0

我認爲你必須在你的Zend_Db_Table_Abstract例如代碼中的錯誤:'$ DB->使用fetchall($ SQL) ;'不適合。 – cypherabe

+0

謝謝,我改變了fetchOne() – kitensei

+0

仍然,我想知道爲什麼你同時執行Zend_Db_Table_Abstract類的find()和Zend_Db_Adapter類的獲取操作; – cypherabe

回答

2

Zend_DB_Abstract將查詢每個PHP請求上的表元數據。

這意味着要做一個DB DESCRIBE TABLE,在某些數據庫上可能會很慢。

爲了避免這種情況,您可以緩存這樣的元數據,這將提高查詢性能:

///////////////////////////// 
    // getting a Zend_Cache_Core object 
    $cache = Zend_Cache::factory('Core', 
     'File', 
     array('lifetime' => 86400, 'automatic_serialization' => true), 
     array('cache_dir' => $config->cacheDir)); 

    // Next, set the cache to be used with all table objects 
    Zend_Db_Table_Abstract::setDefaultMetadataCache($cache); 
+1

這實際上可以用oracle db保存1-2秒! –

1

抽象有一個價格。

Zend是一個php框架,比起像pdo這樣的原生擴展,其詛咒速度要慢得多。 Zend_DB/Zend_Db_Table在運行時創建很多類的實例。 也許你可以用像apc這樣的bytecodecache或zend-server中的build-in來快速運行你的應用程序。

也許HipHop也是你的解決方案。

+0

這是一個事實,但我很想知道,如果我在做一些更簡單的方法之前做錯了事情,我不得不說,我對多重查詢的低性能表現感到驚訝,但也許Zend並沒有做出像thoses這樣的事情。 – kitensei

+0

Zend Framework只是另一個創建,解析和製作類對象而不是僅傳遞數組的對象。如果在這樣的大型DB結構中ZDB增加了大量開銷,我不會感到驚訝。我能想到的唯一的事情就是Zend Server應該能夠很好地與Zend Framework配合使用並編譯優化和性能代碼。我從來沒有嘗試過。 – jmbertucci

1

幾個指針:採用表/行類

  • 總是會稍微慢一點,因爲客觀的額外開銷的(如果是連一個字;))
  • 我的工作場所,我們只是使用原則(1.2)有類似的問題,在接下來的幾周內,我們將用APC(遺憾的是,該文章上的圖像不見了)
  • 我想Zend_Db有一個查詢緩存機制,但我找不到關於它的信息在參考指南
+0

我是一個經常使用Zend Framework(ZF)的用戶,儘管我的應用程序都不足以完成嚴格的性能評估。 ZF使用Zend_Cache來允許你緩存任何東西。你要做的是基本上把你的查詢結果,並讓Zend_Cache使用一些獨特的可識別索引來緩存它們。在上面的例子中,他們的查詢是「WHERE id = 2」,所以索引可能只是「2」或「id2」或其他。然後,在你訪問數據庫之前,你需要用一個簡單的IF(hasCache('id2'))語句來檢查Zend_Cache,然後取出緩存而不是重新查詢數據庫。 – jmbertucci

+0

不幸的是,這不是應用程序的解決方案,數據只是不斷變化(多用戶應用程序)並將查詢結果存儲到緩存中並不是解決方案,但我認爲Zend可能會以某種方式準備查詢,然後更改標識符與佔位符'?' – kitensei

+0

當然,如果值不經常變化,那麼緩存是唯一有價值的,並且如果值發生更改,則必須清除緩存。鑑於我們正在討論的內容,這通常是作爲一個Web應用程序完成的。與某些類似CMS的後端管理員一起添加 - 編輯 - 從數據庫中刪除項目。然後,您可以將清除緩存綁定到添加 - 編輯 - 刪除功能。 *編輯* opps,kitensei只是確認緩存將無法正常工作。 – jmbertucci