Sql 如何防止更改某些值的执行计划

Sql 如何防止更改某些值的执行计划,sql,postgresql,explain,Sql,Postgresql,Explain,我在posgresql9.1.9中有一个表。有一个模式: CREATE TABLE chpl_text ( id integer NOT NULL DEFAULT nextval('chpl_text_id_seq1'::regclass), page_id bigint NOT NULL, page_idx integer NOT NULL, ... ); 我在这个表中有大约40000000(40M)行。 现在,有一个问题: SELECT ... FROM chpl_te

我在
posgresql9.1.9
中有一个表。有一个模式:

CREATE TABLE chpl_text
(
  id integer NOT NULL DEFAULT nextval('chpl_text_id_seq1'::regclass),
  page_id bigint NOT NULL,
  page_idx integer NOT NULL,
  ...
);
我在这个表中有大约40000000(40M)行。 现在,有一个问题:

SELECT
  ...
FROM chpl_text
ORDER BY id
LIMIT 100000
OFFSET N
对于
N=5400000
它会神奇地变成

Limit  (cost=13042543.16..13042793.16 rows=100000 width=52)
  ->  Sort  (cost=13029043.16..13129748.57 rows=40282164 width=52)
        Sort Key: id
        ->  Seq Scan on chpl_text t  (cost=0.00..1056505.64 rows=40282164 width=52)
导致运行时间非常长

如何防止postresql更改更高偏移量的查询计划


注意:我知道,大偏移量根本不好,但我不得不在这里使用它们。

如果Postgres的配置有一半是合理的,那么您的统计数据是最新的(
ANALYZE
或autovacuum),并且成本设置是合理的,Postgres通常更清楚何时进行索引扫描或顺序扫描。详细信息和链接:

要在没有顺序扫描的情况下实际测试性能,请“禁用”它(仅在调试会话中!)

然后再次运行
解释分析

也。使用给定的用例,您应该立即考虑升级到.

您还可以使用CTE和
行号()
尝试此备选查询,查看查询计划是否更有利:

WITH cte AS (
   SELECT ..., row_number() OVER (ORDER BY id) AS rn
   FROM   chpl_text
   )
SELECT ...
FROM   cte
WHERE  rn BETWEEN N+1 AND N+100000
ORDER  BY id;

情况并非总是如此,但可能是在您的特殊情况下。

是否使用默认配置值?您应该尝试增加work_mem和其他与内存相关的参数的数量。根据postgres DOC(),这是预期的。请看一篇类似的文章。你能用EXPLAIN(分析,缓冲区)重复一下吗?
SET enable_seqscan=OFF;
WITH cte AS (
   SELECT ..., row_number() OVER (ORDER BY id) AS rn
   FROM   chpl_text
   )
SELECT ...
FROM   cte
WHERE  rn BETWEEN N+1 AND N+100000
ORDER  BY id;