CakePHP медленный ответ на SQL Server найти

У меня проблема с моим приложением в 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 процесс?

3

Решение

открыто

./Lib/Cake/Model/Datasource/Database/Sqlserver.php

Найти этот текст

PDO::ATTR_CURSOR => PDO::CURSOR_SCROLL

Изменить на

PDO::ATTR_CURSOR => PDO::CURSOR_FWDONLY

Когда я попробовал это в моем CakePHP скорость mssql увеличилась на 50% даже на 100%

3

Другие решения

Это сокращенный код

не укороченный код гораздо актуальнее

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 в целом; но при значительных неудобствах / затратах, связанных с необходимостью управления схемами модели, — стоит обратить внимание, если эта задержка является проблемой, а не если это не так.

0