当“检查X最小值”标志设置为true时,为什么不使用索引?

时间:2019-12-05 09:58:37

标签: postgresql

我对postgres中的一个简单表进行了简单查询。我在那张桌子上有一个简单的索引。

在某些环境中,它在执行查询时使用索引,而在其他环境中(在同一RDS实例,不同的数据库上)则不使用索引。 (使用EXPLAIN ANALYSE检查)

我注意到的一件事是,如果索引上的“ Check X Min”标志为TRUE,则不使用索引。 (pg_catalog.pg_index.indcheckxmin

如何确保使用索引,并且应该将“ Check X Min”标志设置为false?

表包含超过10万行。

我尝试过的事情:

  • 该索引有效,并且始终在“ Check X Min”设置为false的环境中使用。
  • set enable_seqscan to off;仍然不使用索引。
  • 在这些环境中创建/重新创建索引似乎总是将'Check X Min'设置为true。
  • 抽真空似乎无济于事。

表和索引的设置:

CREATE TABLE schema_1.table_1 (
    field_1 varchar(20) NOT NULL,
    field_2 int4 NULL,
    field_3 timestamptz NULL,
    field_4 numeric(10,2) NULL
);
CREATE INDEX table_1_field_1_field_3_idx ON schema_1.table_1 USING btree (field_1, field_3 DESC);

查询:

select field_1, field_2, field_3, field_4
from schema_1.table_1
where field_1 = ’abcdef’
order by field_3 desc limit 1;

不使用索引时:

QUERY PLAN                                                                                                           |
---------------------------------------------------------------------------------------------------------------------|
Limit  (cost=4.41..4.41 rows=1 width=51) (actual time=3.174..3.176 rows=1 loops=1)                                   |
  ->  Sort  (cost=4.41..4.42 rows=6 width=51) (actual time=3.174..3.174 rows=1 loops=1)                              |
        Sort Key: field_3 DESC                                                                                     |
        Sort Method: top-N heapsort  Memory: 25kB                                                                    |
        ->  Seq Scan on table_1  (cost=0.00..4.38 rows=6 width=51) (actual time=3.119..3.150 rows=3 loops=1)|
              Filter: ((field_1)::text = 'abcdef'::text)                                                               |
              Rows Removed by Filter: 96                                                                             |
Planning time: 2.895 ms                                                                                              |
Execution time: 3.197 ms                                                                                             |

使用索引时:

QUERY PLAN                                                                                                                                              |
--------------------------------------------------------------------------------------------------------------------------------------------------------|
Limit  (cost=0.28..6.30 rows=1 width=51) (actual time=0.070..0.144 rows=1 loops=1)                                                                      |
  ->  Index Scan using table_1_field_1_field_3_idx on field_1  (cost=0.28..12.31 rows=2 width=51) (actual time=0.049..0.066 rows=1 loops=1)|
        Index Cond: ((field_1)::text = 'abcdef'::text)                                                                                                    |
Planning time: 0.184 ms                                                                                                                                 |
Execution time: 0.303 ms                                                                                                                                |

已重命名字段,架构和表,以避免共享业务上下文

1 个答案:

答案 0 :(得分:1)

您似乎正在同时使用CREATE INDEX,并且有长期未完成的交易。来自the docs

  

但是,即使那样,索引也可能无法立即用于查询:在最坏的情况下,只要存在早于索引构建开始的事务,就不能使用该索引。

您在这里没有太多选择。寻找并修复您的长期未清交易,不要同时使用,或者忍受限制。