在对一个相当大的应用程序(350个表db,一些表上几百万个条目)中实现的不同库/框架进行一些研究后,我发现Zend_Db很容易做我想做的事:快速切换的适配器管理数据库之间。
问题是性能真的很低,这是一个例子( $ db 是一个基本的适配器,时间只在select / fetch上计算):
SQL QUERY (用于测试的查询,该表包含~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_Abstract :: setDefaultMetadataCache($ cache)进行调整)
$elmt = new Element();
for ($i=0; $i<2000; $i++) {
$elmt->find(2);
}
查询循环会导致zend表演失败。我知道这不是最好的事情,但应用程序已经开发出来了,我很乐意尽可能少地修改代码。
一些想法?我做错了吗?
答案 0 :(得分: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 :(得分:1)
抽象是有代价的。
Zend是一个php框架,它的诅咒比pdo这样的原生扩展要慢得多。 Zend_DB / Zend_Db_Table在运行时创建了许多类实例。 也许你使用像apc这样的bytecodecache或者在zend-server中内置了很快的应用程序。
也许HipHop也是您的解决方案。
答案 2 :(得分:1)
一些指针: