我有下面的简单表,其中包含流量测量数据:
CREATE TABLE "TrafficData"
(
"RoadID" character varying NOT NULL,
"DateID" numeric NOT NULL,
"ExactDateTime" timestamp NOT NULL,
"CarsSpeed" numeric NOT NULL,
"CarsCount" numeric NOT NULL
)
CREATE INDEX "RoadDate_Idx" ON "TrafficData" USING btree ("RoadID", "DateID");
RoadID列唯一标识要记录其数据的道路,而DateID标识数据的一年中的一天(1..365)-基本上是ExactDateTime的四舍五入表示形式。
我有大约100.000.000行;在“RoadID”列中有1.000个不同的值,在“DateID”列中有365个不同的值。
然后,我运行以下查询:
SELECT * FROM "TrafficData"
WHERE "RoadID"='Station_1'
AND "DateID">20100610 AND "DateID"<20100618;
这最多需要三秒钟的时间才能完成,而我一生都无法弄清楚为什么。
EXPLAIN ANALYZE给我以下输出:
Bitmap Heap Scan on "TrafficData" (cost=104.84..9743.06 rows=2496 width=47) (actual time=35.112..2162.404 rows=2016 loops=1)
Recheck Cond: ((("RoadID")::text = 'Station_1'::text) AND ("DateID" > 20100610::numeric) AND ("DateID" < 20100618::numeric))
-> Bitmap Index Scan on "RoadDate_Idx" (cost=0.00..104.22 rows=2496 width=0) (actual time=1.637..1.637 rows=2016 loops=1)
Index Cond: ((("RoadID")::text = 'Station_1'::text) AND ("DateID" > 20100610::numeric) AND ("DateID" < 20100618::numeric))
Total runtime: 2163.985 ms
我的规范:
我将不胜感激任何有用的指示!
最佳答案
较慢的部分是从表中获取数据,因为索引访问似乎非常快。您可以优化RAM使用率参数(请参阅http://wiki.postgresql.org/wiki/Performance_Optimization和http://www.varlena.com/GeneralBits/Tidbits/perf.html),也可以通过发出CLUSTER命令来优化表中数据的布局(请参阅http://www.postgresql.org/docs/8.3/static/sql-cluster.html)。
CLUSTER "TrafficData" USING "RoadDate_Idx";
应该做。
关于performance - Postgres中非常慢的位图堆扫描,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/4009062/