ORM : Cache metadata issue

Hi,

I’m working on a project which includes only a few packages of Cake 3 :

  • cakephp/orm
  • cakephp/validation
  • cakephp/i18n
  • cakephp/cache

I uploaded my project to a production server, and was surprised to see that my queries using the ORM are extremely slow (a query that lasts about 100ms on my local machine can take up to 5 or 10 seconds on the production server).

It seems that there are queries on the information_schema table that take much time and resources. I’ve spent some time on the web and saw that I needed the enable cacheMetaData param in my config in order to cache the queries on information_schema.

My config looks like this :

ConnectionManager::config('default', [
    'className' => 'Cake\Database\Connection',
    'driver' => 'Cake\Database\Driver\Mysql',
    'host' => 'my-host',
    'database' => 'my-database',
    'username' => 'my-username',
    'password' => 'my-password',
    'encoding' => 'utf8',
    'timezone' => 'UTC',
    'cacheMetaData' => true // If set to `true` you need to install the optional "cakephp/cache" package.
]);

I followed the instruction above and installed the cakephp/cache package. But I’m guessing I need to enable it somehow (or somewhere), but can’t figure out how (or where).

Here is what I tried :

\Cake\Cache\Cache::config('_cake_model_', [
     'className' => 'File',
     'prefix' => 'myapp_cake_model_',
     'path' => '/cache/models/',
     'serialize' => true,
     'duration' => '+2 minutes',
]);

But it’s still not working, my cache or cache/models/ folder is still empty and the requests on information_schema are not cached.

How can I fix this ?

Thanks for your time

kinkaz

Are you seeing any errors being emitted related to caching? I think your path of /cache/models might need to be a path relative to your application. You’ll also want to ensure that your webserver can write to the directories that will store your schema metadata.

Thanks for your answer.

Unfortunately, no, my php log file doesn’t include any error related to caching.

  • I just made sure my cache directory’s permissions is set to 777 (same for subdirectories)
  • I also changed the path property to : __DIR__ . '/cache/' (btw I changed it to simply cache and not cache/models anymore)

What’s “funny” is that I tried to config the cache for core and it’s working. My config is :

Cake\Cache\Cache::config('_cake_core_',  [
    'className' => 'File',
    'prefix' => 'myapp_cake_core_',
    'path' =>  __DIR__ . '/cache/',
    'serialize' => true,
    'duration' => '+2 minutes',
]);

When making a POST request, it adds 2 files in my cache directory (myapp_cake_core_translations_default_en__u_s__p_o_s_i_x and myapp_cake_core_translations_cake_en__u_s__p_o_s_i_x) so it’s doesn’t seem to be a permission issue…

That is odd. You can confirm the config has been applied by checking ConnectionManager::get('default')->schemaCollection() you should get a CachedCollection if metadata caching is on. If you do get a cached collection you might want to poke around in Cake\Database\Schema\CachedCollection to see what is going on.

So, I tried ConnectionManager::get('default')->schemaCollection() and didn’t get a CachedCollection, but just a Collection.

Then, I went back on an other project which fully runs CakePHP3 (not just the ORM) and noticed in the configuration file that the parameter cacheMetadata was not written as it is in my project (cacheMetaData). After changing it, everything went fine :slight_smile:

Could you update your documentation on https://packagist.org/packages/cakephp/orm ? Because that’s where I copied/paste the Connection example :

Connecting to the Database

The first thing you need to do when using this library is register a connection object. Before performing any operations with the connection, you need to specify a driver to use:

use Cake\Datasource\ConnectionManager;
ConnectionManager::config('default', [
    'className' => 'Cake\Database\Connection',
    'driver' => 'Cake\Database\Driver\Mysql',
    'database' => 'test',
    'username' => 'root',
    'password' => 'secret',
    'cacheMetaData' => false // If set to `true` you need to install the optional "cakephp/cache" package.
]);

Anyway, thanks for your time :grinning: