0
は、私は単純なクエリを実行します。のPostgreSQL&ActiveRecordのスロークエリ
私はCHANNEL_IDのためのすべての履歴を選択した場合= 1:
History.where(channel_id: 1)
History Load (0.5ms) SELECT "histories".* FROM "histories" WHERE "histories"."channel_id" = 1 [["channel_id", 1]]
それだけで0.5msの
を取り、我々はRubyの配列の助けを借りて、一つのレコードを取るしようとした場合:
History.where(channel_id: 1).order('histories.id DESC').to_a.first
History Load (0.5ms) SELECT "histories".* FROM "histories" WHERE "histories"."channel_id" = 1 ORDER BY id DESC [["channel_id", 1]]
どこに問題があるのでしょうか?
PS:既にchannel_idフィールドにインデックスがあります。
UPD:
History.where(channel_id: 1).order('histories.id DESC').limit(1).explain
History Load (848.9ms) SELECT "histories".* FROM "histories" WHERE "histories"."channel_id" = 1 ORDER BY histories.id DESC LIMIT 1 [["channel_id", 1]]
=> EXPLAIN for: SELECT "histories".* FROM "histories" WHERE "histories"."channel_id" = 1 ORDER BY histories.id DESC LIMIT 1 [["channel_id", 1]]
QUERY PLAN
-------------------------------------------------------------------------------------------------------
Limit (cost=0.43..13.52 rows=1 width=42)
-> Index Scan Backward using histories_pkey on histories (cost=0.43..76590.07 rows=5849 width=42)
Filter: (channel_id = 1)
(3 rows)
通常、channel_id、idの複合インデックスが役立ちます。あなたのユースケースが特別な場合、つまりチャネル '1'だけが必要な場合、[部分インデックス](https://www.postgresql.org/docs/current/static/indexes-partial.html)を設定することができます。 。 – pozs
@pozsコンパウンドインデックス 'channel_id、id'で解決していただきありがとうございます – zolter