activerecord-covering-index
Extends ActiveRecord/Rails to support covering indexes in PostgreSQL using the INCLUDE
clause.
From the PostgreSQL documentation:
The optional INCLUDE clause specifies a list of columns which will be included in the index as non-key columns. A non-key column cannot be used in an index scan search qualification, and it is disregarded for purposes of any uniqueness or exclusion constraint enforced by the index. However, an index-only scan can return the contents of non-key columns without having to visit the index's table, since they are available directly from the index entry. Thus, addition of non-key columns allows index-only scans to be used for queries that otherwise could not use them.
Compatibility
- ActiveRecord 5.2 and later
- PostgreSQL 11 and later
Installation
Add this line to your application's Gemfile:
gem 'activerecord-covering-index'
And then execute:
$ bundle install
Usage
In a migration, use the include
option with add_index
:
class IndexUsersOnName < ActiveRecord::Migration[6.1]
def change
add_index :users, :name, include: :email
end
end
Or within a create_table
block:
class CreateUsers < ActiveRecord::Migration[6.1]
def change
create_table :users do |t|
t.string :name
t.string :email
t.
t.index :name, include: :email
end
end
end
You can also include
multiple columns:
add_index :users, :name, include: [:email, :updated_at]
Or combine include
with other index options:
add_index :users, :name, include: :email, where: 'email IS NOT NULL', unique: true
Caveats
Non-key columns are not included in the name Rails generates for an index. For example, the following two indexes will receive the same name, which causes the second to raise a PG::DuplicateTable
error:
add_index :users, :name
add_index :users, :name, include: :email
To avoid collisions, you can specify a different name:
add_index :users, :name, include: :email, name: 'index_users_on_name_include_email'
Development
After checking out the repo, run bin/setup
to install dependencies. Then, run rake spec
to run the tests. You can also run bin/console
for an interactive prompt that will allow you to experiment.
To install this gem onto your local machine, run bundle exec rake install
. To release a new version, update the version number in version.rb
, and then run bundle exec rake release
, which will create a git tag for the version, push git commits and tags, and push the .gem
file to rubygems.org.
Contributing
Bug reports and merge requests are welcome on GitLab at https://gitlab.com/schlock/activerecord-covering-index.
License
The gem is available as open source under the terms of the MIT License.
Credits
The gem was adapted from https://github.com/rails/rails/pull/37515, created by @sebastian-palma.