Doesn't the indexing with :artwork_id and :viewer_id (the last line of
indexing in the code) already make an index for the :artwork_id?
No. A compound index is only used when you query on both columns - thats the whole point. Its a an index of the combinations.
irb(main):001:0> ArtworkShare.where(viewer_id: 1).explain
ArtworkShare Load (0.8ms) SELECT "artwork_shares".* FROM "artwork_shares" WHERE "artwork_shares"."viewer_id" = $1 [["viewer_id", 1]]
=> EXPLAIN for: SELECT "artwork_shares".* FROM "artwork_shares" WHERE "artwork_shares"."viewer_id" = $1 [["viewer_id", 1]]
QUERY PLAN
------------------------------------------------------------------------------------------------
Bitmap Heap Scan on artwork_shares (cost=4.20..13.67 rows=6 width=40)
Recheck Cond: (viewer_id = '1'::bigint)
-> Bitmap Index Scan on index_artwork_shares_on_viewer_id (cost=0.00..4.20 rows=6 width=0)
Index Cond: (viewer_id = '1'::bigint)
(4 rows)
irb(main):002:0> ArtworkShare.where(viewer_id: 1, artwork_id: 1).explain
ArtworkShare Load (1.7ms) SELECT "artwork_shares".* FROM "artwork_shares" WHERE "artwork_shares"."viewer_id" = $1 AND "artwork_shares"."artwork_id" = $2 [["viewer_id", 1], ["artwork_id", 1]]
=> EXPLAIN for: SELECT "artwork_shares".* FROM "artwork_shares" WHERE "artwork_shares"."viewer_id" = $1 AND "artwork_shares"."artwork_id" = $2 [["viewer_id", 1], ["artwork_id", 1]]
QUERY PLAN
------------------------------------------------------------------------------------------------------------------------
Index Scan using index_artwork_shares_on_artwork_id_and_viewer_id on artwork_shares (cost=0.15..8.17 rows=1 width=40)
Index Cond: ((artwork_id = '1'::bigint) AND (viewer_id = '1'::bigint))
(2 rows)
And that migration is well... pretty bad.
class CreateArtworkShares < ActiveRecord::Migration[6.0]
def change
create_table :artwork_shares do |t|
t.belongs_to :artwork, null: false, foreign_key: true
t.belongs_to :viewer, null: false, foreign_key: true
t.timestamps
end
add_index :artwork_shares, [:artwork_id, :viewer_id], unique: true
end
end
This adds foreign key constraints and indexes on artwork_id
and viewer_id
. It also creates bigint
instead of regular integer columns.
I was also wondering if there was an easy way to decide on the ordering of the columns in the last indexing line.
No. There is no easy way. It depends on the access paths in the application.