我在Sinatra有一个使用Postgres和ActiveRecord的应用程序。我已将ActiveRecord迁移转换为下面的原始sql:
CREATE TABLE "locations" (
"id" bigserial primary key,
"latitude" character varying,
"longitude" character varying,
"speed" integer, "course" integer,
"agent_uuid" character varying,
"recorded_at" timestamp,
"created_at" timestamp NOT NULL,
"updated_at" timestamp NOT NULL
)
CREATE INDEX "index_locations_on_agent_uuid_and_recorded_at" ON "locations" ("agent_uuid", "recorded_at")
CREATE INDEX "index_locations_on_recorded_at" ON "locations" ("recorded_at")
该表格有4m +行的用户位置,可以通过手机进行ping操作。我想为所有用户返回最后5分钟的位置。该查询需要5秒多的时间才能完成,这太长了,理想情况下我希望这个时间不到0.5秒。
我使用以下查询查询db表:
SELECT * FROM
locations as l
WHERE
l.recorded_at >= (DATE '2017-10-20')
AND l.recorded_at < (DATE '2017-10-28')
ORDER BY
recorded_at DESC;
运行EXPLAIN ANALYZE VERBOSE BUFFERS报告:
Sort (cost=151034.25..151034.57 rows=126 width=85) (actual time=5609.589..5609.662 rows=253 loops=1)
Output: id, latitude, longitude, speed, course, agent_uuid, recorded_at, created_at, updated_at
Sort Key: l.recorded_at DESC
Sort Method: quicksort Memory: 60kB
Buffers: shared hit=25051 read=49475
-> Seq Scan on public.locations l (cost=0.00..151029.85 rows=126 width=85) (actual time=314.955..5609.469 rows=253 loops=1)
Output: id, latitude, longitude, speed, course, agent_uuid, recorded_at, created_at, updated_at
Filter: ((l.recorded_at >= '2017-10-28 15:00:00'::timestamp without time zone) AND (l.recorded_at < '2017-10-28 15:05:00'::timestamp without time zone))
Rows Removed by Filter: 5117974
Buffers: shared hit=25051 read=49475
Planning time: 0.081 ms
Execution time: 5609.721 ms
然而它仍然很慢。有没有人有任何想法如何加快这一点,我不知所措。非常感谢任何想法。
一旦我将迁移运行到index_locations_on_recorded_at,这大大加快了查询速度。迁移后的报告是:
Index Scan Backward using index_locations_on_recorded_at on public.locations l (cost=0.43..522.07 rows=169 width=85) (actual time=0.040..0.188 rows=253 loops=1)
Output: id, latitude, longitude, speed, course, agent_uuid, recorded_at, created_at, updated_at
Index Cond: ((l.recorded_at >= '2017-10-28 15:00:00'::timestamp without time zone) AND (l.recorded_at < '2017-10-28 15:05:00'::timestamp without time zone))
Buffers: shared hit=235
Planning time: 0.157 ms
Execution time: 0.885 ms
感谢您的帮助。