【发布时间】:2012-12-09 12:08:37
【问题描述】:
我定义了下表和索引:
CREATE TABLE ticket (
wid bigint NOT NULL DEFAULT nextval('tickets_id_seq'::regclass),
eid bigint,
created timestamp with time zone NOT NULL DEFAULT now(),
status integer NOT NULL DEFAULT 0,
argsxml text,
moduleid character varying(255),
source_id bigint,
file_type_id bigint,
file_name character varying(255),
status_reason character varying(255),
...
)
我在created 时间戳上创建了一个索引,如下所示:
CREATE INDEX ticket_1_idx
ON ticket
USING btree
(created );
这是我的查询:
select * from ticket
where created between '2012-12-19 00:00:00' and '2012-12-20 00:00:00'
在记录数量开始增长(大约 500 万条)之前一直运行良好,但现在需要很长时间才能返回。
解释分析揭示了这一点:
Index Scan using ticket_1_idx on ticket (cost=0.00..10202.64 rows=52543 width=1297) (actual time=0.109..125.704 rows=53340 loops=1)
Index Cond: ((created >= '2012-12-19 00:00:00+00'::timestamp with time zone) AND (created <= '2012-12-20 00:00:00+00'::timestamp with time zone))
Total runtime: 175.853 ms
到目前为止,我已经尝试过设置:
random_page_cost = 1.75
effective_cache_size = 3
同时创建:
create CLUSTER ticket USING ticket_1_idx;
没有任何作用。我究竟做错了什么?为什么选择顺序扫描?索引应该使查询快速。有什么可以优化的吗?
【问题讨论】:
-
它没有进行顺序扫描。它正在执行索引扫描。
-
另外它只需要 175 毫秒即可运行。如果需要很长时间,则 OP 可能有一个庞大的数据集,需要很长时间才能通过网络传输,而不是运行查询。\
-
顺便说一句:
effective_cache_size=3可能有点太低了。 (但在这种情况下可能不会有害) -
你为什么认为 175ms 是“年龄”?
-
不要使用
select *,因为它会增加要传输到客户端的结果集大小。
标签: postgresql indexing query-optimization database-partitioning postgresql-performance