timestamp列上的date_trunc不返回任何内容

时间:2014-03-09 11:24:57

标签: postgresql postgresql-9.1

在将截断的字段与date_trunc()进行比较后,从db中检索记录时出现了一个奇怪的问题。

此查询不会返回任何数据:

select id from my_db_log 
 where date_trunc('day',creation_date) >= to_date('2014-03-05'::text,'yyyy-mm-dd');

但是,如果我将creation_date列添加到id,那么它会返回数据(即select id, creation_date...)。

我有另一个列last_update_date具有相同类型,当我使用该列时,仍然会执行相同的操作。

select id from my_db_log
 where date_trunc('day',last_update_date) >= to_date('2014-03-05'::text,'yyyy-mm-dd');

与之前类似。如果我id, last_update_dateselect {。}},它也会返回记录

现在进一步深入挖掘,我在creation_date子句中添加了last_updated_datewhere,这次要求在select子句中同时使用select id, creation_date, last_update_date子句有记录(即id serial NOT NULL, creation_date timestamp without time zone NOT NULL DEFAULT now(), last_update_date timestamp without time zone NOT NULL DEFAULT now(), CONSTRAINT db_log_pkey PRIMARY KEY (id), )。

有没有人遇到过同样的问题?这种类似的东西适用于我的其他具有此类列的表格!

如果有帮助,这是我的表架构:

EXPLAIN (FORMAT XML)

我之前提出过一个不同的问题但没有得到任何答案。这个问题可能与那个问题有关。如果你对这个感兴趣,请点击the link

带有select *

EDITS :: <explain xmlns="http://www.postgresql.org/2009/explain"> <Query> <Plan> <Node-Type>Result</Node-Type> <Startup-Cost>0.00</Startup-Cost> <Total-Cost>0.00</Total-Cost> <Plan-Rows>1000</Plan-Rows> <Plan-Width>658</Plan-Width> <Plans> <Plan> <Node-Type>Result</Node-Type> <Parent-Relationship>Outer</Parent-Relationship> <Alias>my_db_log</Alias> <Startup-Cost>0.00</Startup-Cost> <Total-Cost>0.00</Total-Cost> <Plan-Rows>1000</Plan-Rows> <Plan-Width>658</Plan-Width> <Node/s>datanode1</Node/s> <Coordinator-quals>(date_trunc('day'::text, creation_date) &gt;= to_date('2014-03-05'::text, 'yyyy-mm-dd'::text))</Coordinator-quals> </Plan> </Plans> </Plan> </Query> </explain>

{{1}}

1 个答案:

答案 0 :(得分:2)

“不可能”现象

返回的行数完全,与SELECT子句中的项无关。 (但请参阅@ Craig关于SRF的评论。)你的数据库中必须有破坏。 也许是破损的覆盖指数?当您引入附加列时,强制Postgres访问表本身。尝试重新索引:

REINDEX TABLE my_db_log;

REINDEX上的手册。或者:

VACUUM FULL ANALYZE my_db_log;

更好的查询

无论哪种方式,请改为使用:

select id from my_db_log 
where creation_date >= '2014-03-05'::date

或者:

select id from my_db_log 
where creation_date >= '2014-03-05 00:00'::timestamp

'2014-03-05'采用ISO 8601格式。您可以将此字符串文字强制转换为date。不需要to_date(),可以使用任何区域设置。与datetimestamp [without time zone])相比,creation_date会自动强制为timestamp [without time zone]。关于Postgres时间戳的更多细节:
Ignoring timezones altogether in Rails and PostgreSQL

此外,你在这里投掷date_trunc()也没有任何收获。相反,您的查询将会变慢,并且无法使用列上的任何普通索引(可能会使更慢)