Open bradeaton opened 4 years ago
Each database system implements multi-tenancy on his own way. Mysql has the use
statement to change between databases, postgres has schemas, etc.
But, as you have use_schemas
set to false, you're not using the schemas mecanism, instead, you're changing your connection on runtime each time you call to switch!
I don't know the inner workings of active record/apartment, but Apartment calls establish_connection who creates a new pool. Creating new connections is a really expensive operation, that's why we create connection pools and re-use them when possible, but, each you switch tenants, apartment is creating a new pool. This is a really expensive operation.
From the Readme: One can optionally use the full database creation instead if they want, though this is not recommended
I don't think this is an issue, for me it would me an expected outcome when using full database instead of schemas.
I don't know if it's the entire cause but when you change the search path, postgresql will replan prepared statements.
See notes: https://www.postgresql.org/docs/current/sql-prepare.html
I have plans of basically adding .where('? = ?', search_path, search_path)
. to force some heavier prepared statements to not get replanned.
We're attempting to implement apartment in our existing Rails 4.2 application. We've run into a performance issue that we can't seem to get around. The crux of the issue seems to be that database queries that we execute after doing an Apartment::Tenant.switch take significantly longer than if we are not switching tenants. It seems as if optimizations that we were getting from PostgreSQL without switching tenants are lost once we switch. We see this issue even when there aren't any separate private databases configured. In the steps to reproduce below config.tenant_names is set to an empty hash so that everything is still in the primary database. The difference in DB performance illustrated in the steps to reproduce are seen across all the queries we've looked at so far. The results are just slower response times, it brings the application to a crawl and then a halt with average page load times above 15 seconds or more.
Steps to reproduce
Expected behavior
I would expect the average time to execute the account.users query with tenant switching and without to be at least close. I would expect some overhead in the switch.
Actual behavior
The query times where we are switching tenants in between are x times longer than when we are not switching tenants. Here are the benchmark results:
System configuration
Heroku
PostgreSQL 10.11
2.2.1
Apartment config (in
config/initializers/apartment.rb
or so):use_schemas
: (true
orfalse
) falseRails (or ActiveRecord) version: 4.2
Ruby version: 2.4.5