惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
Jina AI
Jina AI
博客园 - Franky
Apple Machine Learning Research
Apple Machine Learning Research
酷 壳 – CoolShell
酷 壳 – CoolShell
阮一峰的网络日志
阮一峰的网络日志
量子位
雷峰网
雷峰网
宝玉的分享
宝玉的分享
V
Visual Studio Blog
博客园_首页
小众软件
小众软件
The Cloudflare Blog
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
大猫的无限游戏
大猫的无限游戏
博客园 - 聂微东
S
SegmentFault 最新的问题
博客园 - 【当耐特】
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
博客园 - 叶小钗
月光博客
月光博客
博客园 - 三生石上(FineUI控件)
人人都是产品经理
人人都是产品经理
WordPress大学
WordPress大学

博客园 - MSSQL123

timescaledb 扩展 PostgreSQL 18+ 版本下源码编译安装 ubuntu24下 ext4和xfs类型磁盘以及PostgreSQL实例性能对比测试 PostgreSQL 17 流复制中开启逻辑复制槽同步,以及逻辑槽的故障转移 记一次PostgreSQL交叉表crosstab行转列导致的OOM TiDB 扩容与缩容 PostgreSQL 高可用集群 patroni 自动故障转移测试 Ubuntu 20 环境下 patroni 自动化安装,一分钟快速搭建 patroni 集群 Ubuntu 20 环境下 pg_auto_failover 自动化安装,一分钟快速搭建pg_auto_failover集群 PostgreSQL的消息队列扩展pgmq 磁盘IO延迟和队列深度的关系 TiDB 最小拓扑架构集群安装 PostgreSQL 逻辑复制中的同步和异步模式以及其表现 prometheus 的 altermanager Silences静默告警,优雅地抑制告警 “世界上百分之99的博士和他们的论文都是垃圾”,原本以为这个观点偏激 pg_auto_failover 在多种场景下自动故障转移的验证 pgbouncer连接池设置与压力测试的最大连接数测试 pg_auto_failover 自动故障转移参数 博文阅读密码验证 - 博客园 pg_auto_failover 高可用中,PostgreSQL实例配置文件的加载步骤 pg_auto_failover集群monitor节点的高可用 prometheus监控Linux Server node_exporter代理安装和配置 prometheus监控windows window_exporter代理安装和配置 Prometheus 和 Grafana 监控 PostgreSQL 记一次MySQL binlog日志导致磁盘空间占满的问题 SQLServer 2019 标准版在虚拟机上无法充分利用CPU的问题诊断 Windows Failover Cluster集群中的EventId 1196错误日志 pg_auto_failover 环境变量导致的show命令错误 SqlServer 事务复制(transaction replication)的复制位点信息 SqlServer 事务复制的两个参数immediate_sync,allow_anonymous MySQL,SqlServer,PostgreSQL中,如何实现锁定一张表
PostgreSQL 18 新特性 skip scan,一个鸡肋的功能
MSSQL123 · 2026-07-02 · via 博客园 - MSSQL123

skip scan是什么

Skip Scan PostgreSQL 18版本中一个新特性,原理在复合索引中,当前导列缺失、但前导列基数较小的情况下,通过“多次索引扫描”来替代全表扫描的优化技术。

举例:
假设索引为CREATE INDEX idx_1 ON t3(c2, c3);
对于如下两个查询,都能用到索引
WHERE c2 = 10 AND c3 = 563782;
WHERE c2 = 10;
对于非前导列的查询,如下,是无法使用到索引的。
WHERE c3 = 563782;

感觉这个功能非常鸡肋,被人少部分人炒作成什么“令人兴奋的特性”,感觉有点夸张了。

SQLServer中的skip scan特性

开始之前先看一下所谓的skip scan在SQLServer中的表现,SQLServer中没有强调skip scan是一个特性,印象中是自古以来就有的特性,执行计划中体现为Index Scan。

如下测试环境为SQLServer 2019,对于上文中的场景,SQLServer的index scan在查询条件非索引的前导列的情况下,通过“扫描”索引实现查询的目的,如下case
另:SQLServer真正实现索引查找的叫index seek,也即二分法查询,而index scan是索引扫描,扫整个索引。


create table t1
(
	c1 int identity(1,1),
	c2 int,
	c3 int,
	c4 varchar(100),
	constraint pk_t1 primary key(c1)
);


create index idx_1 on t1(c2,c3);


while 1>0
begin
	insert into t1 
	select rand()*100000,rand()*1000000,newid() 
end

select count(1) from t1;



select * from t1 where c3 = 594981;

image

PostgreSQL 18 的skip scan

如下测试环境为PostgreSQL 18.3,对于上文中的场景,前导列,这里的基数超过10000的话,就不会走index scan了,而是走全表扫描Seq Scan ,这里有一个限制,既然是这样,那为什么不把基数更大的字段作为前导列呢,Skip Scan又有什么意义呢


create table t3
(
	c1 int generated always as identity,
	c2 int,
	c3 int,
	c4 varchar(100),
	constraint pk_t1 primary key(c1)
);

truncate table t3;

INSERT INTO public.t3 (c2, c3, c4)
SELECT 
  	random()*100000,		--前导列,这里的基数超过100000的话,就不会走skip scan了,而是走全表扫描Seq Scan ,这里有一个限制,既然是这样,那为什么不把基数更大的字段作为前导列呢,Skip Scan又有什么意义呢
  	random()*1000000,
    clock_timestamp()   
FROM generate_series(1, 1000000);

select * from t3 limit 100;

create index idx_1 on t3(c2,c3);

analyze  t3;

explain analyze 
select * from t3 where  c3 = 563782

image

只有在前导列的基数足够小的情况下,类似查询才会使用到 skip scan,正如上面提到的,如果说测试case中的c2的基数足够小,如下case,那么在创建复合索引的时候,把c2放在前面合理吗?
如果把c3作为前导列,也即create index idx_1 on t3(c3,c2);那么,就完全用不到skip scan的特性了。
那么就不需要用到skip scan这个特性了,所以感觉这个特性很鸡肋,同时对比SQLServer,实现的也不怎么好。基数稍微大一点就无法用到skip scan这个特性了。
image