我有一张表pings
,里面有大约 1500 万行。我在 postgres 9.2.4 上。它具有的相关列是一个外键monitor_id
、一个created_at
时间戳和一个response_time
表示毫秒的整数。这是确切的结构:
Column | Type | Modifiers
-----------------+-----------------------------+----------------------------------------------------
id | integer | not null default nextval('pings_id_seq'::regclass)
url | character varying(255) |
monitor_id | integer |
response_status | integer |
response_time | integer |
created_at | timestamp without time zone |
updated_at | timestamp without time zone |
response_body | text |
Indexes:
"pings_pkey" PRIMARY KEY, btree (id)
"index_pings_on_created_at_and_monitor_id" btree (created_at DESC, monitor_id)
"index_pings_on_monitor_id" btree (monitor_id)
我想查询所有没有的响应时间NULL
(90% 不会NULL
,大约 10% 会NULL
),具有特定的monitor_id
,并且是在上个月创建的。我正在使用 ActiveRecord 进行查询,但最终结果如下所示:
SELECT "pings"."response_time"
FROM "pings"
WHERE "pings"."monitor_id" = 3
AND (created_at > '2014-03-03 20:23:07.254281'
AND response_time IS NOT NULL)
这是一个非常基本的查询,但运行大约需要 2000 毫秒,这似乎相当慢。我假设索引会使它更快,但我尝试过的所有索引都不起作用,我假设这意味着我没有正确索引。
当我运行时EXPLAIN ANALYZE
,这就是我得到的:
Bitmap Heap Scan on pings (cost=6643.25..183652.31 rows=83343 width=4) (actual time=58.997..1736.179 rows=42063 loops=1) Recheck Cond: (monitor_id = 3) Rows Removed by Index Recheck: 11643313 Filter: ((response_time IS NOT NULL) AND (created_at > '2014-03-03 20:23:07.254281'::timestamp without time zone)) Rows Removed by Filter: 324834 -> Bitmap Index Scan on index_pings_on_monitor_id (cost=0.00..6622.41 rows=358471 width=0) (actual time=57.935..57.935 rows=366897 loops=1) Index Cond: (monitor_id = 3)
所以最后有一个索引monitor_id
正在使用,但没有别的。我已经使用monitor_id
,created_at
和尝试了复合索引的各种排列和顺序response_time
。我试过按created_at
降序排列索引。我已经尝试使用response_time IS NOT NULL
.
我没有尝试过使查询更快。您将如何优化和/或索引它?