1

比方說,你有三種型號:的ActiveRecord與Postgres的:有許多通過和索引

class Collection < ActiveRecord::Base 
    has_many :comments, through => :users 
end 

class User < ActiveRecord::Base 
    belongs_to :collection 
    has_many :comments 
end 

class Comment < ActiveRecord::Base 
    belongs_to :user 
end 

使用索引像這樣:

add_index :users, :collection_id 
add_index :comments, :user_id 

如果你有徵求意見的收集查詢:

@collection.comments 

它會使用兩個索引嗎?

編輯:

這將產生一個查詢,看起來像:

SELECT "comments".* FROM "comments" INNER JOIN "users" ON "comments"."user_id" = "users"."id" WHERE "users"."collection_id" = 232 

使用EXPLAIN它聲稱它只是使用 「索引掃描使用index_users_on_collection_id上的用戶」

因此推測它會用戶從collection_id上的用戶索引中快速找到用戶,然後在與用戶加入時查找所有評論?如果有很多評論(假設,如100,000),這個查詢不會很好地執行嗎?

謝謝。

+2

而不是對'EXPLAIN'輸出是什麼的模糊描述,爲什麼不顯示它?更好的是,顯示'EXPLAIN ANALYZE'輸出,所以我們可以看到*期望*行數和成本以及*實際*行數和時間。此外,不要指望大數據集上的計劃與小數據集上的計劃相同。 – kgrittn 2012-04-27 12:36:43

+2

執行計劃並不是假設性的,它們是基於當前基數的估計以及所考慮的過濾器和連接字段的選擇性。如果您認爲該計劃在100K評論中會很慢,那麼只有在您制定了包含100K評論和當前統計數據的計劃時,這一計劃纔會起作用。如果您有實際的性能問題,請運行併發布@解析分析,如@ kilrittn所示。 – dbenhur 2012-04-28 00:05:33

+0

通常,評論來自* one *用戶。所以你的數據模型可能不符合要求。可能應該是n:1而不是n:m - 帶有引用作者('user')的外鍵列的表'comment'。 – 2012-05-10 03:51:06

回答

0

您不能依靠小表的EXPLAIN計劃對大表來說是一樣的。計劃隨着表格大小的變化而變化

這就是說,如果它最終通過註釋進行順序掃描並且存在大量行,那麼您可能需要確保註釋表上的外鍵字段上有一個索引。 PostgreSQL將使用該索引,如果它評估這將是從磁盤I/O角度來看的淨勝利,並且這意味着該表足夠大以利於使用索引掃描,並且索引掃描不會檢索大部分的表格。