是否可以在postgresql中更改索引的执行顺序?

问题描述 投票:0回答:1

我在我的postgresql数据库中创建了一个测试表,试图描述这个问题。表名:test列:id(varchar,uuid),created_at(时间戳)

我将一些模拟数据插入表中。

postgres=# select count(1) from test;
  count
---------
 1200001
(1 row)

这里是查询A:

postgres=# explain select id from test
postgres-# where id > '67542377-b900-4084-b619-bae9448a73b5'
postgres-# and created_at >= '2020-04-17 08:23:22.229' and created_at < '2020-04-17 08:24:26.474'
postgres-# order by id limit 1000;
                                                                                  QUERY PLAN
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
 Limit  (cost=2335.83..2338.33 rows=1000 width=37)
   ->  Sort  (cost=2335.83..2381.98 rows=18460 width=37)
         Sort Key: id
         ->  Index Scan using index_create_at on test  (cost=0.43..1323.69 rows=18460 width=37)
               Index Cond: ((created_at >= '2020-04-17 08:23:22.229'::timestamp without time zone) AND (created_at < '2020-04-17 08:24:26.474'::timestamp without time zone))
               Filter: ((id)::text > '67542377-b900-4084-b619-bae9448a73b5'::text)
(6 rows)

然后是查询B:

postgres=# explain select id from test
postgres-# where id > '67542377-b900-4084-b619-bae9448a73b5'
postgres-# and created_at >= '2020-04-17 08:23:22.229' and created_at < '2020-04-17 08:40:26.474'
postgres-# order by id limit 1000;
                                                                             QUERY PLAN
--------------------------------------------------------------------------------------------------------------------------------------------------------------------
 Limit  (cost=0.43..122.60 rows=1000 width=37)
   ->  Index Scan using test_pkey on test  (cost=0.43..87966.38 rows=720001 width=37)
         Index Cond: ((id)::text > '67542377-b900-4084-b619-bae9448a73b5'::text)
         Filter: ((created_at >= '2020-04-17 08:23:22.229'::timestamp without time zone) AND (created_at < '2020-04-17 08:40:26.474'::timestamp without time zone))
(4 rows)

我注意到执行计划由于有所不同的created_at值而有所不同。在此示例中,postgres优化器似乎做出了正确的决定(此成本很低)。

但是在生产数据库中,有数十亿的数据。那么查询B将非常慢。

我尝试以不同的方式编写查询B以尝试更改执行索引的顺序,但是失败了。计划没有改变。

postgres=# explain select id from
postgres-# (select id from test where created_at >= '2020-04-17 08:23:22.229' and created_at < '2020-04-17 08:40:26.474') t1
postgres-# where id > '67542377-b900-4084-b619-bae9448a73b5'
postgres-# order by id limit 1000;
                                                                             QUERY PLAN
--------------------------------------------------------------------------------------------------------------------------------------------------------------------
 Limit  (cost=0.43..122.60 rows=1000 width=37)
   ->  Index Scan using test_pkey on test  (cost=0.43..87966.38 rows=720001 width=37)
         Index Cond: ((id)::text > '67542377-b900-4084-b619-bae9448a73b5'::text)
         Filter: ((created_at >= '2020-04-17 08:23:22.229'::timestamp without time zone) AND (created_at < '2020-04-17 08:40:26.474'::timestamp without time zone))
(4 rows)

因此可以更改查询B计划以强制其使用与查询A相同的计划吗?

postgresql indexing sql-execution-plan
1个回答
0
投票

通常,您不能强制查询使用特定索引,但是可以通过更好的统计信息,重写查询或某些设置参数来影响查询计划器。

请参阅相关讨论:How do I force Postgres to use a particular index?Postgres query optimization (forcing an index scan)

© www.soinside.com 2019 - 2024. All rights reserved.