Annotate ActiveRecord queries not using index #31760
Merged
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Description
This PR adds a red
[NO INDEX]
annotation to ActiveRecord SQL notifications (printed in Rails development console by default) for queries where the MySQL query result has theno_index_used
flag set:Before:
After:
This should provide some lightweight DB-optimization guidance for development and debugging.
It also adds a
raise_on_no_index_used
Rails configuration option, which will enforce index usage by raisingNoIndexUsedException
if any ActiveRecord query is executed without using an index. This option is disabled by default, since MySQL often chooses to ignore an existing index for small or empty tables where the query optimizer decides that a table scan will be more efficient anyway. (I thought I would include the option anyway, just in case it may be eventually useful.)Background
The MySQL client/server protocol distinguishes queries that make use of an index for efficient lookup, and those that do not use an index (sometimes called 'full table scan' queries). This information is passed in the Status Flags of the OK packet produced with every MySQL-protocol query response, and is set to the
:no_index_used
key of theMysql2::Result#server_flags
object produced by themysql2
gem.Implementation
This PR adds a Rails initializer that patches the
ActiveRecord::ConnectionAdapters::Mysql2Adapter
to add text to thename
-key string on thesql.active_record
notification generated for every query, when theno_index_used
flag on theResult
object is set.Future work
SUM_NO_INDEX_USED
column of theperformance_schema.events_statements_summary_by_digest
Performance Schema summary table to monitor no-index-usage in production.Testing story
Manual testing and the existing test suite which could verify that nothing will break as a result of this change.
Tests covering the actual behavior in this PR are deferred fro now- this PR was done quickly to help address an existing pain point in development, and creating a reliable test-case with a no-index query might not be trivial.