У меня проблема с моим приложением в 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
процесс?
открыто
./Lib/Cake/Model/Datasource/Database/Sqlserver.php
Найти этот текст
PDO::ATTR_CURSOR => PDO::CURSOR_SCROLL
Изменить на
PDO::ATTR_CURSOR => PDO::CURSOR_FWDONLY
Когда я попробовал это в моем CakePHP скорость mssql увеличилась на 50% даже на 100%
Это сокращенный код
не укороченный код гораздо актуальнее
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;
}
родительский метод только заполняет кеш (в _cake_model_
config cache), время кеширования по умолчанию в производственном режиме 999 дней и в разработке это десять секунд. Учитывая описание, которое вы в данный момент находитесь в режиме разработки — признайте, что (хотя это довольно неудобно), это в основном проблема среды разработки.
Есть несколько решений, но самым простым на сегодняшний день является простое кэширование данных дольше, независимо от режима отладки / производства. Для этого просто измените соответствующая конфигурация кеша:
Cache::config('_cake_model_', array(
...
'duration' => '+999 days' # <-
));
Если есть изменение схемы, вам нужно помнить, чтобы очистить кеш, иначе ваше приложение не узнает об этом.
Гораздо более навязчивое решение (переопределяющая модель schema
а также setSource
, жесткое кодирование схем моделей, чтобы приложение не запрашивало базу данных, чтобы знать) удалило бы вызовы listSources
в целом; но при значительных неудобствах / затратах, связанных с необходимостью управления схемами модели, — стоит обратить внимание, если эта задержка является проблемой, а не если это не так.