Postgresql上时间戳字段的正确索引

时间:2015-01-03 19:09:34

标签: sql postgresql indexing

这是表格

CREATE TABLE material
(
  mid bigserial NOT NULL,
...
  active_from timestamp without time zone,
....
  CONSTRAINT material_pkey PRIMARY KEY (mid),
)

CREATE INDEX i_test_t_year
  ON material
  USING btree
  (date_part('year'::text, active_from));

如果我按照中场进行排序

select mid from material order by mid desc
"Index Only Scan Backward using material_pkey on material  (cost=0.29..3573.20 rows=100927 width=8)"

但如果我使用active_from进行排序

select * from material order by active_from desc
"Sort  (cost=12067.29..12319.61 rows=100927 width=16)"
"  Sort Key: active_from"
"  ->  Seq Scan on material  (cost=0.00..1953.27 rows=100927 width=16)"

也许active_from的索引​​错了?如何以较低的成本制造正确的

2 个答案:

答案 0 :(得分:0)

date_part上的索引('年' :: text,active_from)不能用于按active_from排序; 知道按照该函数排序然后通过active_from进行排序,只需按照active_from进行排序,但postgresql没有排序。如果您创建以下索引:

CREATE INDEX i_test_t_year ON material (active_from);

然后postgresql将能够用它来回答查询:

Index Scan Backward using i_test_t_year on material  (cost=0.15..74.70 rows=1770 width=16)

但是,请记住postgresql只会使用索引,如果它认为它比顺序扫描然后排序更快,那么创建正确的索引并不能保证它将用于此查询。

答案 1 :(得分:0)

你需要完全理解一个指数,我相信这会回答你的问题。

索引实际上是一个存储在其自身内存旁边的查找。你从字面上看索引,然后指向要获取的行。

如果查看索引,您所存储的内容是从“active_from”列中提取的“年份”的TEXT值。

因此,如果您要查看索引,它看起来就像是一堆条目:

2015
2015
2014
2014
2013
etc.

它们存储为TEXT值,而不是时间戳。

在您的查询中,您将DESC命名为时间戳值。

所以它与索引不匹配,因为你已经存储了它。

如果您将查询中的ORDER BY设置为“order by date_part('year':: text,active_from)”,那么它将调用您放在那里的索引。

所以我建议你只需在“active_from”上添加索引,而不要解析日期。