oracle-enhanced: Schema loading performance regression after update from rails 5.1 to rails 5.2
Steps to reproduce
Background is that we’re experiencing massive performance issues since updating to rails 5.2. Looking at the logs, it seems that structural database statements make the difference. To isolate this, we performed db:cache:dump multiple times, both with rails 5.1 and rails 5.2.
The difference is startling (see next 2 sections).
This may be related to #1673.
Expected behavior
Executing db:cache:dump of a large application under Rails 5.1:
unknown : 3936 ms
Sequence : 320 ms
Primary Key : 9551 ms
-------------------------------
total : 13807 ms
The results are grouped by query type (the string before the parenthesized time in the rails log) and are the average over multiple runs.
Actual behavior
Executing db:cache:dump of the same application under Rails 5.2:
tables : 809 ms
views : 504 ms
synonyms : 1987 ms
Sequence : 6270 ms
Primary Key : 134574 ms
Column definitions : 30425 ms
current schema : 6 ms
table exists : 181 ms
unknown : 9 ms
-------------------------------
total : 174765 ms
This is over 12x slower than with Rails 5.1.
System configuration
Rails version: 5.1 / 5.2
Oracle enhanced adapter version: 1.8.2 / 5.2.2
Ruby version: jruby 9.1.14.0 (2.3.3) 2017-11-08 2176f24 Java HotSpot™ 64-Bit Server VM 25.66-b17 on 1.8.0_66-b17 +jit [darwin-x86_64]
Oracle Database version: Oracle Database 12c Enterprise Edition Release 12.1.0.2.0 - 64bit Production
Final thoughts
As always a ton of thanks to you for looking at this and I’m sorry I couln’t provide an isolated performance test – I hope that comparing the database statements of the two log files will do the trick!
About this issue
- Original URL
- State: closed
- Created 6 years ago
- Comments: 39 (10 by maintainers)
Commits related to this issue
- Introduce column cache per connection rsim/oracle-enhanced#1490 removed Oracle enhanced adapter own column cache feature to use Rails `db:schema:cache:dump`. However, it caused slower performance ab... — committed to yahonda/oracle-enhanced by yahonda 6 years ago
- Add table_name search condition to `indexes(table_name)` method and restored one spec which has been removed at https://github.com/rsim/oracle-enhanced/pull/1672 Related to #1720 — committed to yahonda/oracle-enhanced by yahonda 6 years ago
- Use cursor_sharing = force by default again it actually reverts #1503 rsim/oracle-enhanced#1498 implemented prepared statements for dictionary queries. However #1713 restored non-prepared statements ... — committed to yahonda/oracle-enhanced by yahonda 6 years ago
- Introduce column cache per connection rsim/oracle-enhanced#1490 removed Oracle enhanced adapter own column cache feature to use Rails `db:schema:cache:dump`. However, it caused slower performance ab... — committed to yahonda/oracle-enhanced by yahonda 6 years ago
- Introduce column cache per connection rsim/oracle-enhanced#1490 removed Oracle enhanced adapter own column cache feature to use Rails `db:schema:cache:dump`. However, it caused slower performance ab... — committed to yahonda/oracle-enhanced by yahonda 6 years ago
- Introduce column cache per connection rsim/oracle-enhanced#1490 removed Oracle enhanced adapter own column cache feature to use Rails `db:schema:cache:dump`. However, it caused slower performance ab... — committed to yahonda/oracle-enhanced by yahonda 6 years ago
Oracle enhanced adapter 5.2.3 has been released which should address this issue. Thanks for everyone who investigated and tested some test branches.
One possible reason is changing the execution plan may cause a longer elapsed time.
If you are using Oracle Database 12c Release 1, how about disabling
optimizer_adaptive_featuresexplained in these articles:Since these parameters are changing in every database versions, I am not thinking about setting these parameters in Oracle enhanced adapter itself.
@yahonda Thank you for turning.
I’m using multiple activerecord versions at my gem CI
AR 5.2.0 + oracle-enhanced v5.2.2build is very very slow, but It seems this issue was fixed at https://github.com/rsim/oracle-enhanced/issues/1720#issuecomment-409207938 (yahonda/oracle-enhanced@2dc2ef9)Benchmark
c.f. https://github.com/sue445/index_shotgun/pull/48
Thank you.
Thanks for the testing everyone.
I have made several changes: Actually my environment does not get performance improvement by adding a search condition.
Please give it a try and let me know the result.
Thank you.
@yahonda thank you for taking a look at this. Using your branch, my findings were sadly similar to those of @InteNs - the
indexesquery takes ~6000ms each time, and runs for every table being dumped.However, I found the further addition of:
to the query reduced the execution time from ~6000ms to ~15ms - perhaps worth rolling in too? As far as I can see, because this query is no longer cached it needn’t get results for all indexes every time.
@yahonda running
rails db:schema:dumpon this branch results in utter slowness (compared to https://github.com/jlahtinen/oracle-enhanced/tree/optimize_schema_statement)the main issue is retrieving indexes with the query as defined below.
edit:
rails db:schema:dump RAILS_ENV=productionquery takes more than 5000 ms
our production database is
oracle 12cour test database is
oracle 11g expressI was able to increase db:migration time a lot with https://github.com/jlahtinen/oracle-enhanced/tree/optimize_schema_statement
I used rule optimizer also, but left outer join increased performance from 25s to 1.5s in that modified query. It also seems like this query is used multiple times in 5.2 branch and not in 5.1 branch.
@yahonda maybe you are able to check if this is done correctly and merge it to your branches
It is likely due to execution plan change for this query https://github.com/rsim/oracle-enhanced/blob/fb1cbbf1498b452fa2fff32e8c3cd90c0d144363/lib/active_record/connection_adapters/oracle_enhanced_adapter.rb#L557-L565
Would you change each change to see if you see performance improvement.
database.ymlto usecursor_sharing: :forceBackground:
Oracle enhanced adapter 5.2.0 #1498 introduces bind values for dictionary queries then default value of
cursor_sharingchanged fromforceto using the database instance value, likelyexact.However, to address #1678 Oracle enhanced adapter 5.2.1 reverted some of changes made #1498 to use sql literals. The query for primary key is one of them.
Thank you.