You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为SELECT DISTINCT ON创建的索引无效?为何仍执行顺序扫描?

SCD Type2查询未使用索引的问题解答

问题背景

我创建了如下player表:

CREATE TABLE public.player (
    company_id character varying NOT NULL,
    id character varying NOT NULL,
    created_at timestamp with time zone DEFAULT CURRENT_TIMESTAMP NOT NULL,
    updated_at timestamp with time zone,
    name character varying NOT NULL,
    family character varying,
    start_from timestamp with time zone DEFAULT now() NOT NULL,
    surrogate_key character varying NOT NULL
);

为实现缓慢变化维度(SCD)Type 2,我执行了以下查询以获取每个surrogate_key的最新记录:

SELECT DISTINCT ON ( surrogate_key ) surrogate_key, * FROM player ORDER BY surrogate_key, created_at DESC;

查询功能正常,但执行计划显示采用顺序扫描(Seq Scan):

Unique  (cost=10.47..10.99 rows=101 width=171) (actual time=0.098..0.115 rows=101 loops=1)
  ->  Sort  (cost=10.47..10.73 rows=103 width=171) (actual time=0.097..0.100 rows=103 loops=1)
        Sort Key: surrogate_key, created_at DESC
        Sort Method: quicksort  Memory: 46kB
        ->  Seq Scan on player  (cost=0.00..7.03 rows=103 width=171) (actual time=0.013..0.039 rows=103 loops=1)
Planning Time: 0.076 ms
Execution Time: 0.135 ms

我创建了匹配查询的索引:

CREATE INDEX ON player (surrogate_key, created_at DESC);

但执行计划仍显示顺序扫描,想知道:这是否正常?索引创建是否错误?“创建索引就不会用顺序扫描”的想法是否有误?

解答

这是正常现象,你的索引创建完全正确,优化器选择顺序扫描的核心原因是当前表数据量太小(仅103行)。

PostgreSQL的查询优化器会基于成本选择执行计划:对于极小的数据集,顺序扫描不需要额外的索引IO和查找开销,直接全表读取后排序的成本反而比走索引更低——你当前的执行时间仅0.135ms,已经是最优状态了。

你的索引(surrogate_key, created_at DESC)完美匹配查询需求:

  • 满足DISTINCT ON (surrogate_key)的分组逻辑
  • 完全对齐ORDER BY surrogate_key, created_at DESC的排序顺序

当表数据量增长到一定规模(比如数万行),优化器会自动切换为索引扫描,此时可以跳过全表排序,直接通过索引有序读取每个surrogate_key的第一条(最新)记录,性能会显著提升。

若要验证索引有效性,可临时禁用顺序扫描强制测试:

SET enable_seqscan = off;
SELECT DISTINCT ON ( surrogate_key ) surrogate_key, * FROM player ORDER BY surrogate_key, created_at DESC;

查看此时的执行计划,会看到索引扫描(Index Scan)的逻辑,证明索引可用。


内容的提问来源于stack exchange,提问作者Fred Hors

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.26 20:37:48