选择返回不一致的数据

时间:2014-07-28 17:12:41

标签: postgresql postgresql-9.3

这怎么可能?

insight=> select id from analysis_analysis where status != 'finished' and status != 'archived' and begin_at < '2014-07-28 17:23:27' limit 1;
  id   
-------
 46632
(1 row)

insight=> select id from analysis_analysis where id = 46632 ;
 id 
----
(0 rows)

我在同一台机器/主机/服务器上同时执行这些查询。我有两个小时相同的结果。

修改 根据要求,这里是解释查询:

insight=> explain select id from analysis_analysis where status != 'finished' and status != 'archived' and begin_at < '2014-07-28 17:23:27' limit 1;
                                                                             QUERY PLAN                                                                              
---------------------------------------------------------------------------------------------------------------------------------------------------------------------
 Limit  (cost=0.00..4.61 rows=1 width=4)
   ->  Seq Scan on analysis_analysis  (cost=0.00..15286.67 rows=3317 width=4)
         Filter: (((status)::text <> 'finished'::text) AND ((status)::text <> 'archived'::text) AND (begin_at < '2014-07-28 17:23:27'::timestamp without time zone))
(3 rows)

insight=> explain select id from analysis_analysis where id = 46632 ;
                                             QUERY PLAN                                              
-----------------------------------------------------------------------------------------------------
 Index Only Scan using analysis_analysis_pkey on analysis_analysis  (cost=0.41..8.43 rows=1 width=4)
   Index Cond: (id = 46632)
(2 rows)

修改

我尝试重建索引,现在又出现了另一个错误:

insight=> select id from analysis_analysis where id = 46632 ;
ERROR:  tuple offset out of range: 0
insight=> select id from analysis_analysis where id = 46633 ;
  id   
-------
 46633
(1 row)

修改

我重建索引(再次)现在,查询结果为空(如最初的那样)

修改

另一个问题:

insight=> select id from analysis_analysis where id >= 46630 and id <= 46635;
  id   
-------
 46630
 46631
 46633
 46634
 46635
(5 rows)

1 个答案:

答案 0 :(得分:2)

可能在analysis_analysis(id)上有一个索引,不知何故它已损坏,你的第一个查询不使用它,但第二个查询因数据损坏而失败。

尝试第二个查询:

SET enable_indexscan TO off;

如果不一致来自索引,这次结果将是正确的。

索引如何被破坏?

  • 早期版本的postgresql 9.3.x有一些可能导致此问题的错误,请查看release notes

  • 硬件问题。

在SQL中,您可以使用

REINDEX INDEX index_name;

从头开始重建。