I have a problem with my app in CakePHP 2.7.1, with Sqlserver Datasource.
When I do a find
operation on any table, the response time is extremely slow (more than 1 minute).
I did the research with XDebug + QCachegrind and I found out that the problem is Sqlserver->listSources()
, which lists all the 1385 tables on the database.
This is the shortened code (core file 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;
}
I put a simple microtime
benchmark around the while
block and nearly all the process time is taken by these 3 lines.
Is there any way to speed up this?
Is there any way to tell CakePHP not to do the listSources
process?
The not-shortened code is much more relevant:
The parent method only populates the cache (in the
_cake_model_
cache config), the default cache time in production mode is 999 days and in development it's ten seconds. Given the description you're currently in development mode - recognise that (whilst pretty inconvenient) it's basically a development-environment problem.There are a couple of solutions, but the simplest by far is to just cache the data for longer, and irrespective of debug/production mode. To do so just change the relevant cache config:
If there's a schema change you'll need to remember to clear the cache, otherwise your app won't know about it.
The much-more-intrusive solution (overriding model
schema
andsetSource
, hardcoding the model schemas so the app doesn't have to query the db to know) would remove the calls tolistSources
altogether; but at the significant inconvenience/cost of you needing to manage your model schemas - worth pursuing if this delay is a problem, and not if it isn't.