0
我运行简单的查询:的PostgreSQL和ActiveRecord的 - 慢查询
History.where(channel_id: 1).order('histories.id DESC').first
结果:
History Load (808.8ms) SELECT "histories".* FROM "histories" WHERE "histories"."channel_id" = 1 ORDER BY histories.id DESC LIMIT 1 [["channel_id", 1]]
808.8ms 7 1的记录与CHANNEL_ID = 1。总的历史数为2110443。
如果我选择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的
如果我们试图采取一个纪录红宝石阵列的帮助:
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