我的应用程序在Sqlserver数据源的CakePHP 2.7.1中遇到了问题。
当我在任何表上执行find操作时,响应时间都非常慢(超过1分钟)。
我使用XDebug + QCachegrind进行了研究,我发现问题出在Sqlserver->listSources()上,它列出了数据库上的所有1385个表。
这是缩短的代码(核心文件lib\Cake\Model\Datasource\Database\Sqlserver.php:172)
public function listSources($data = null) {
$result = $this->_execute("SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES");
while ($line = $result->fetch(PDO::FETCH_NUM)) {
$tables[] = $line[0];
}
return $tables;
}我在while块周围放置了一个简单的microtime基准测试,几乎所有的处理时间都由这3行代码占用。
有没有什么方法可以加速这个过程?
有没有办法告诉CakePHP不要执行listSources过程?
发布于 2017-05-03 12:08:28
打开
./Lib/Cake/Model/Datasource/Database/Sqlserver.php查找此文本
PDO::ATTR_CURSOR => PDO::CURSOR_SCROLL更改为
PDO::ATTR_CURSOR => PDO::CURSOR_FWDONLY当我在我的cakephp中尝试时,mssql速度提高了50%甚至100%
发布于 2015-09-14 16:36:23
这是简短的代码
not-shortened code更加相关:
public function listSources($data = null) {
$cache = parent::listSources();
if ($cache !== null) {
return $cache; # <-
}
$result = $this->_execute("SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES");
if (!$result) {
$result->closeCursor();
return array();
}
$tables = array();
while ($line = $result->fetch(PDO::FETCH_NUM)) {
$tables[] = $line[0];
}
$result->closeCursor();
parent::listSources($tables); # <-
return $tables;
}parent method仅填充缓存(在_cake_model_缓存配置中),即生产模式is 999 days和开发it's ten seconds中的默认缓存时间。根据你目前处于开发模式的描述-认识到(虽然相当不方便)这基本上是一个开发环境问题。
有几种解决方案,但到目前为止最简单的是只缓存更长时间的数据,而不考虑调试/生产模式。为此,只需更改relevant cache config
Cache::config('_cake_model_', array(
...
'duration' => '+999 days' # <-
));如果有模式改变,你需要记得清除缓存,否则你的应用程序不会知道它。
更具侵入性的解决方案(覆盖模型schema和setSource,对模型模式进行硬编码,这样应用程序就不必查询数据库才能知道)将完全删除对listSources的调用;但这会带来管理模型模式的极大不便/成本-如果这种延迟是一个问题,则值得追求,如果不是问题,就不值得追求。
https://stackoverflow.com/questions/32237303
复制相似问题