我的CakePHP 2.7.1中的应用程序存在问题,带有Sqlserver数据源。
当我在任何桌面上执行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;
}
我在microtime
块周围放置了一个简单的while
基准,几乎所有处理时间都由这3行进行。
有没有办法加快这个?
有没有办法告诉CakePHP不要进行listSources
过程?
答案 0 :(得分:4)
打开
./Lib/Cake/Model/Datasource/Database/Sqlserver.php
查找此文
PDO::ATTR_CURSOR => PDO::CURSOR_SCROLL
更改为
PDO::ATTR_CURSOR => PDO::CURSOR_FWDONLY
当我尝试在我的cakephp mssql速度增加50%甚至100%
答案 1 :(得分:0)
这是缩短的代码
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
,对模型模式进行硬编码,以便应用程序不必查询数据库以了解)将删除对{{{}的调用1}}完全;但是你需要管理你的模型模式会带来很大的不便/成本 - 如果这个延迟是一个问题,那就值得追求,而不是如果不是。