IndexScan比SeqScan返回的结果更少,索引损坏?

Postgresql | 执行计划 postgresql 执行计划 阅读详情

关于作者:

Nickyoung,数据库领域从业者。PostgreSQL ACE,IvorySQL专家顾问委员会成员。

公众号 “ 👉 PostgreSQL 运维之道 ”。

给大家分享一个有趣的案例,同一个 sql,索引扫描比全表顺序扫描获取的数据更少。本篇我们深入分析一起索引排序规则损坏的案例,并 debug 验证索引扫描的主要过程。

问题现象

走索引扫描查询到 1 条数据。

testidx=# explain analyze select *  from user_info where userid ='1230005998';
                                                          QUERY PLAN                                                           
-------------------------------------------------------------------------------------------------------------------------------
 Index Scan using index_userid on user_info  (cost=0.28..35.61 rows=9 width=57) (actual time=0.030..0.032 rows=1 loops=1)
   Index Cond: ((userid)::text = '1230005998'::text)
 Planning Time: 0.118 ms
 Execution Time: 0.057 ms
(4 rows)

testidx=# select ctid,userid,region_id from user_info where userid ='1230005998';
  ctid  | userid    | region_id 
--------+----------------------+-----------
 (4,39) | 1230005998 | abc
(1 row)

不走索引顺序扫描查询到 11 条数据。

testidx=# set enable_indexscan to off;
SET
testidx=# explain analyze select * from user_info where userid ='1230005998';
                                                QUERY PLAN                                                
----------------------------------------------------------------------------------------------------------
 Seq Scanon user_info  (cost=0.00..51.50rows=9 width=57) (actual time=0.093..0.460rows=11 loops=1)
   Filter: ((userid)::text = '1230005998'::text)
   Rows Removed by Filter: 1309
 Planning Time: 0.116 ms
 Execution Time: 0.478 ms
(5rows)

testidx=# select ctid,userid,region_id from user_info where userid ='1230005998';
  ctid   | userid    | region_id 
---------+----------------------+-----------
 (4,39)  | 1230005998 | abc
 (9,14)  | 1230005998 | abc
 (9,32)  | 1230005998 | abc 
 (10,32) | 1230005998 | abc
 (12,5)  | 1230005998 | abc
 (26,23) | 1230005998 | abc
 (27,4)  | 1230005998 | abc
 (27,9)  | 1230005998 | abc
 (27,11) | 1230005998 | abc
 (34,38) | 1230005998 | abc
 (34,39) | 1230005998 | abc
(11rows)

testidx=#

对比两次查询结果,可以看到走索引扫描时,仅查询到第一条匹配的数据,对应 ctid 为(4,39)。索引损坏了?

问题分析

当我们怀疑索引损坏时,可以使用 amcheck 插件对索引进行扫描分析,检查是否存在异常。

可以看到 leaf page 8 的 itemoffset 24 和 25 违反了条目顺序不变性规则。即按照升序原则 24 号索引槽位对应的键值要小于等于 25 槽位,但经检查是大于的,所以排序规则混乱了。

testidx=# select * from bt_index_check('index_userid',true);
DEBUG:  StartTransaction(1) name: unnamed; blockState: DEFAULT; state: INPROGRESS, xid/subid/cid: 0/1/0
DEBUG:  verifying level 1 (true root level)
DEBUG:  verifying 7 items on internal block 3
DEBUG:  verifying level 0 (leaf level)
DEBUG:  verifying 207 items on leaf block 1
DEBUG:  verifying 204 items on leaf block 2
DEBUG:  verifying 204 items on leaf block 4
DEBUG:  verifying 204 items on leaf block 5
DEBUG:  verifying 204 items on leaf block 6
DEBUG:  verifying 235 items on leaf block 7
DEBUG:  verifying 78 items on leaf block 8
ERROR:  item order invariant violated for index "index_userid"
DETAIL:  Lower index tid=(8,24) (points to heap tid=(4,14)) higher index tid=(8,25) (points to heap tid=(9,14)) page lsn=1/331E9F98.
testidx=# 

使用 pageinspect 扩展,查看 leaf page 8 有 78 条记录,其中 itemoffset 24 和 25 对应的键值,24 的键值为’31 09 xxx’,25 的键值为’2b 4c xxx’,前者大,确实是有问题的。

testidx=# select * from bt_page_stats('index_userid',8);
 blkno | type | live_items | dead_items | avg_item_size | page_size | free_size | btpo_prev | btpo_next | btpo | btpo_flags 
-------+------+------------+------------+---------------+-----------+-----------+-----------+-----------+------+------------
     8 | l    |         78 |          0 |            31 |      8192 |      5356 |         7 |         0 |    0 |          1
(1 row)

testidx=# 
testidx=# select * from  bt_page_items('index_userid',8) where itemoffset in (22,23,24,25);
 itemoffset |  ctid  | itemlen | nulls | vars |                                  data                                   
------------+--------+---------+-------+------+-------------------------------------------------------------------------
         22 | (4,39) |      32 | f     | t    | 2b 4c 54 34 33 36 32 35 31 33 34 00 00 00 00 00 00 00 00 00 00 00 00 00
         23 | (4,9)  |      32 | f     | t    | 31 09 0d 0a 4c 54 34 33 36 32 35 31 33 34 37 33 36 30 30 37 39 30 30 32
         24 | (4,14) |      32 | f     | t    | 31 09 0d 0a 4c 54 34 33 36 32 35 31 33 34 37 33 36 30 30 37 39 30 30 32
         25 | (9,14) |      32 | f     | t    | 2b 4c 54 34 33 36 32 35 31 33 34 00 00 00 00 00 00 00 00 00 00 00 00 00
(4 rows)

testidx=#

明显的索引损坏了,怎么损坏的呢?

可能是 BUG 或者系统异常导致数据库 crash 等写坏, 还有一个glibc 版本差异导致索引损坏的场景,特别是 glibc 2.28 之前和之后的版本。

经过排查这次异常就是 glibc 差异导致的,glibc 版本从 2.17 到 2.28。

当遇到这样的索引损坏场景时,建议 reindex 对应的索引来修复。

这个问题基本分析清楚了,不过老杨不打算到此为止。 借此机会证实下索引扫描的逻辑,也搞清楚为什么仅扫描一条数据就结束。感兴趣的朋友可以继续往下看。

原理分析

btree 想必大家都很熟悉了(其实我很讨厌面试中对于 btree 的八股文,haha…)

再来回顾下结构,细节可以参考灿灿的书中btree 章节

01.png

检索的时候,从 root page 开始检索,在 leaf page 中找到键值匹配的 heap ctid,通过 ctid 去 heap 中 fetch 对应的数据。这里借用德哥画的图,来自github 博客。

02.png

另外 postgrespro 的博客btree 章节,对于检索过程描述的不错,推荐大家去看看。

例如查找等于 49 的数据,标黄部分及蓝色箭头描述了检索过程:从 root 节点出发,找到第一个匹配的 leaf 节点,顺着 leaf 节点的链表一直查找,直到检索完所有匹配的 leaf 节点。

03.png

简单回顾一些概念和原理后,我们上手 debug 来证实检索过程。

我们的检索条件为userid ='1230005998'

1. 先确定 first leaf page

btgettuple函数中首次扫描走_bt_first函数逻辑。

通常 leaf page 会有多个,扫描时通过二分查找,先找到键值匹配的目标 leaf page。 在_bt_first 函数中,调用_bt_search 函数,再调用_bt_binsrch 函数进行二分查找。

初始的 low 为 1,high 为 8 对应 index_userid 这个索引的 leaf block 1 和 8

_bt_compare 函数进行 key 匹配,这里 userid 为 text 类型,因此使用的比较函数为 bttextcmp

04.png

我们省去二分查找的过程,最终 high=low=8,确定目标数据在 leaf page 8

05.png

2、确定 first item

开始扫描目标 leaf page,同样采用二分查找,找到第一条匹配的 item。

_bt_first 函数走到 offnum = _bt_binsrch(rel, &inskey, buf),在_bt_binsrch 函数中初始 high 为 78,low 为 1(因为 leaf page 8 有 78 条 item)。

06.png

在多轮二分查找后,mid 为 22 时_bt_compare 匹配到了预期数据。bttextcmp 函数中可以看到 text_cmp 入参 arg1, arg2 相同,都为 1230005998,result 为 0。

07.png

因此,low 为 22,high 为 22,找到了 first item。

08.png

3、遍历页面元组,设置扫描边界

while (offnum <= maxoff)循环,offnum 为 22,maxoff 为 78。

从 first item 即 offnum=22 开始遍历,_bt_readpage 中调用_bt_checkkeys 首次比较结果相同,itemIndex++为 1,continuescan 为 true,offnum 延顺到 Next 即 23。

09.png

循环中再次调用_bt_checkkeys 进行比较,实际的比较函数为 texteq,offnum 为 23 时 key 值明显和检索条件的长度不同,值肯定是不同的,result 为 false。

10.png

result 传递给 test,因此*continuescan = false,_bt_checkkeys 返回 false。

11.png

continuescan 为 false,因此 so->currPos.moreRight=false,so->currPos.firstItem = 0, so->currPos.lastItem = 1 - 1, so->currPos.itemIndex = 0;

就是这几个属性决定了扫描边界。 firstItem 和 lastItem 相同都为 0,说明扫描的范围就是 first Item 这一条数据。

12.png

index_getnext_slot 函数中根据 ctid(4,39)调用 index_fetch_heap 获取 heap 数据。

13.png

4、获取 next Item

btgettuple 函数中,后续扫描调用_bt_next 函数。

so->currPos.moreRight 为 false,_bt_readnextpage 函数 return false,因此_bt_steppage 函数 return false

14.png

因此_bt_next 函数返回 false,btgettuple 返回 false

15.png

index_getnext_tid 函数返回 NULL

16.png

tid 为 NULL,index_getnext_slot 函数返回 NULL

17.png

至此扫描结束。

从这个过程中可以看到,itemoffset 22 即记录 ctid(4,39)这条索引键值和检索条件匹配,但 23 不匹配,因此导致索引扫描结束,只扫描了一条数据。

从 seqscan 结果看,ctid (4,39)下一条符合条件的数据为(9,14),对应到索引 itemoffset 25。从 bt_page_items 的结果来看,23 和 24 的键值是一样的,都比 25 大,因此索引排序规则是错乱的。

小结

本篇我们深入分析了一起索引排序规则损坏的案例,当出现类似问题时,可以利用 amcheck 和 pageinspect 扩展来分析解决。同时也 debug 证实了下索引扫描的一些关键过程。


HOW 2026 议题招募中

2026 年 4 月 27-28 日,由 IvorySQL 社区联合 PGEU(欧洲 PG 社区)、PGAsia(亚洲 PG 社区)共同打造的 HOW 2026(IvorySQL & PostgreSQL 技术峰会) 将再度落地济南。届时,PostgreSQL 联合创始人 Bruce Momjian 等顶级大师将亲临现场。

自开启征集以来,HOW 2026 筹备组已感受到来自全球 PostgreSQL 爱好者的澎湃热情。为了确保大会议题的深度与广度,我们诚邀您在 2026 年 2 月 27 日截止日期前,提交您的技术见解。

投递链接:https://jsj.top/f/uebqBc

执行计划 Seq Scan 真相:为何它不一定需要全表扫描 ? PostgreSQL数据库执行计划 Seq Scan 的隐秘优化场景 阅读详情

相关推荐

【信息科学与工程学】信息科学领域工程——第十一篇 数据库基础101 数据库的知识体系07

—关系演算的方程式体系清楚地定义了哪些查询是可以表达的/哪些是不可以表达的。这帮助数据库设计者理解何时需要使用扩展功能(如递归查询、窗口函数等)。第四,

weixin_49199313的博客 49

PostgreSQL DBA(6) - SeqScan vs IndexScan vs Bit...

本节介绍了PostgreSQL中数据表的三种扫描类型,分别是顺序扫描SeqScan、索引扫描IndexScan和位图堆扫描BitmapHeapScan。 一、简介 选择率=条件过滤后的元组数/条件过滤前...

752

AI漫剧制作全流程零基础实操指南:从剧本到剪辑

AI漫剧是一种利用AI工具将剧本、分镜、出图、配音、剪辑整合为流水线的短视频内容形式。其技术原理基于文生图、图生图与文本转语音模型的组合,核心挑战在于角色一致性控制与分镜批量出图。这项技术大幅降低了视频制作门槛,使个人创作者无需演员和设备即可产出剧情向短内容,广泛应用于短视频平台的情景剧、玄幻、甜宠等题材。本文给出了一套零基础可照做的全流程实操方案,覆盖剧本提示词、分镜表、出图选型、配音合成与剪辑模板,帮助你快速跑通AI漫剧制作链路。

weixin_29048309的博客 537

PostgreSQL 中 index scan 与 seq scan 的对比学习

数据量很小的时候,我们可以看到,seq scan 比 index scan 更加有效。那是因为 index scan 至少要发生两次I/O,一次是 读取索引块, 一次是读取数据块。当index 很大的时候,情况可能会更加复杂。  postgres=# select a.relpages, a.reltuples, a.relfilenode,a.reltype,b.typname fro

日积月累终会滴水穿石 7778

E28 LoRa模块透传 定点传输 RSSI测试与MicroPython应用

测试说明 测试模块数:3 测试模式:配置模式和传输模式 如果没有检测到串口,首先检查是否安装串口驱动CH341SER,下载链接,提取码:vaw2 工作模式 模式(0-3) M2 M1 M0 模式介绍 备注 0 传输模式 1 0 0 串口打开,无线打开,连续透明传输 空速支持手动配置和自适应波特率自动调节;连续模式双方波特率必须一致 1 RSSI 1 0 1 串口打开,无线打开,RSSI功能打开 模块每100ms输出RSSI强度值 2 测距模式 1 1 0 保留 - 3 配置模式

GniLAY1022的博客 4243

首个FDA认证开源医学影像AI平台Comp2Comp:从CT自动分析到临床部署全解析

深度学习模型在医学影像分析领域正成为变革性力量,其核心原理是通过卷积神经网络自动学习图像特征,实现精准分割与检测。这一技术价值在于将高度依赖医生经验的定性、主观判断,转化为高效、客观、可重复的定量分析,极大提升了诊断的一致性和工作效率。在应用场景上,医学影像AI已广泛渗透于疾病筛查、辅助诊断、预后评估及治疗方案规划等多个环节。本文聚焦于获得FDA 510(k)认证的开源平台Comp2Comp,它集成了主动脉钙化评分和椎体骨密度分析双任务,通过串联式的U-Net分割网络与目标检测模型,构建了从DICOM预处理

weixin_33725126的博客 653

列举GaussDB(DWS)常见的查询时索引失效场景

使用GaussDB(DWS)时,有时为了加快查询速度,需要对表建立索引。有时我们会遇到明明建立了索引,查询计划中却发现索引没有被使用的情况。本文将列举几种常见的场景和优化方法。

华为云官方博客 2229

企业知识库AI助手的权限管理架构:如何实现细粒度控制?

在展开架构设计前,我们需要先明确“细粒度权限”的核心定义,并理解它对AI助手的特殊意义。权限管理的“粒度”,本质是权限控制的精准程度。维度粗粒度权限细粒度权限资源范围entire document(整个文档)field/paragraph(字段/段落)操作类型read/write(读/写)generate_summary/download/export(生成摘要/下载/导出)上下文约束无(静态权限)time/ip/device(时间/IP/设备)适用场景简单系统(如内部wiki)

大数据洞察的博客 1042

PostgreSQL查询扫描原理

扫描方法的原理包括 seqscan、index scan、index only scan、bitmap scan 等。

sig321的专栏 1582

【图像超分】论文精读:Interpreting Super-Resolution Networks with Local Attribution Maps(LAM)

论文题目:Interpreting Super-Resolution Networks with Local Attribution Maps —— 用局部归因图解释超分辨率网络CVPR 2021!必读文章!必须会的可视化手段!很多文章中都会对比LAM!图像超分辨率 (SR) 技术发展迅速,受益于深度网络的发明及其连续突破。然而,众所周知,深度学习和深度神经网络很难解释。SR网络继承了这种神秘的性质,很少有作品试图理解它们。在本文中,我们对 SR 网络进行了归因分析。

主要更新底层视觉(去噪、超分等)相关的科研内容,形式为【论文精读】+【论文复现】 548

【100%通过率】华为OD机试真题 C++ 实现【打印机队列】【2022.11 Q4 新题】

有5台打印机打印文件,每台打印机有自己的待打印队列。因为打印的文件内容有轻重缓急之分,所以队列中的文件有1~10不同的代先级,其中数字越大优先级越高。打印机会从自己的待打印队列中选择优先级最高的文件来打印。如果存在两个优先级一样的文件,则选择最早进入队列的那个文件。现在请你来模拟这5台打印机的打印过程。

MISAYAONE的博客 9947

IndexScan比SeqScan结果少?先排查这5类原因再决定重建索引

数据库查询优化中,执行计划是理解SQL性能与结果差异的核心工具。当IndexScan与SeqScan返回行数不一致时,很多开发者第一反应是索引损坏,但实际绝大多数情况源于统计信息过期、MVCC快照差异或部分索引定义等逻辑因素。掌握EXPLAIN ANALYZE中的actual rows,并系统核对索引条件与过滤条件,才能避免误判。本文从执行计划的基本原理切入,梳理导致IndexScan结果偏少的常见场景,并给出PostgreSQL与MySQL下的检测工具和在线重建索引的实操建议,帮助你在遇到类似问题时按顺序

weixin_31155097的博客 235

杰理AC695N芯片跑iic接口的oled驱动分享

本文介绍了一个基于IIC接口的0.96寸OLED显示屏驱动程序,适用于SSD1306控制器。驱动采用软件模拟IIC方式,支持字符、数字、字符串、汉字和图片显示,测试平台为杰理AC695N系列芯片。硬件参数包括128×64分辨率,IIC接口(地址0x78),使用IO_PORTA_02(SDA)和IO_PORTA_03(SCL)引脚。驱动包含OLED主文件(oled.c/h)、软件IIC实现(soft_iic.c/h)和字体/图片数据文件(oledfont.h/bmp.h),可通过修改soft_iic.h中的引

qq_42014563的博客 883

PostgreSQL索引扫描比全表扫描少?排查索引损坏的完整指南

数据库查询优化器会在索引扫描(IndexScan)与全表扫描(SeqScan)之间选择不同的执行路径,但两条路径返回的行数不一致时,很多人会第一时间怀疑索引物理损坏。实际上,这种现象大多与“索引损坏”无关,而是由部分索引(Partial Index)的定义、SQL 中 count(col) 与 count(*) 对 NULL 值的语义差异,以及 MVCC 并发快照导致的数据集变化所引起。排查时应当按执行计划、索引定义、SQL 语义、事务快照的顺序逐层验证,最后才使用 amcheck 等工具做物理结构体检。掌

weixin_32576389的博客 152

prometheus普罗米修斯集监控外部k8s

prometheus普罗米修斯集监控外部k8s

你是我一生的追求 2250

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

IndexScan比SeqScan返回少?先别重建索引,可能是快照差异惹的祸

在数据库运维中,当IndexScan返回的行数比SeqScan少时,很多DBA的第一反应是索引损坏并急于执行REINDEX。然而,这类差异往往源于事务快照和并发写入造成的“时间差”,而非物理损坏。理解两种扫描路径的底层原理——索引本质是TID导航表,可见性判断始终发生在堆表层——是区分真假故障的关键。通过使用REPEATABLE READ固定快照、统一count(*)对比口径,可以快速验证索引健康性;同时还需排查部分索引、表达式索引、Index Only Scan与可见性映射等易混淆场景。若确认真正损坏,再

weixin_32466193的博客 251

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

postgres执行计划 seqscan,indexscan,bitmapscan实验性分析

执行以下代码create table t1(c1 int4); insert into t1 select generate_series(1,10); explain analyze select * from t1 where c1 =4 显示为 "Seq Scan on t1 (cost=0.00..40.00 rows=12 width=4) (actual time=0.007.

yibei8811的专栏 1万+

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版

Part-E1-SDIO-Specification-Ver4.00-Final-120220.pdf:最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版,包括SDIO 接口的外设,SDIO 接口官方协议等。

我对PostgreSQL 中 index scan 与 seq scan 的对比学习

开始 数据量很小的时候,我们可以看到,seq scan 比 index scan 更加有效。那是因为 index scan 至少要发生两次I/O,一次是 读取索引块, 一次是读取数据块。当index 很大的时候,情况可能会更加复杂。 postgres=# select a.relpages, a.reltuples, a.relfilenode,a.r...

weixin_33805743的博客 1689

PostgreSQL 查询执行计划深度解析 —— Seq Scan vs Index Scan vs Bitmap Scan 详解

PostgreSQL 查询执行计划核心扫描方式解析 本文深入解析 PostgreSQL 的三大核心扫描方式:顺序扫描(Seq Scan)、索引扫描(Index Scan)和位图扫描(Bitmap Scan)。通过执行计划示例详细说明每种扫描的原理、适用场景及优化建议,并对比它们的 I/O 模式、适用结果集大小等关键特性。文章还介绍了高级扫描类型如仅索引扫描(Index Only Scan),以及规划器基于成本估算的决策机制,包括 SSD 环境下的参数优化建议。最后通过实战案例演示如何针对不同查询场景选择最优

csdn_tom_168的博客 1524

postgresql分页用法_PostgreSQL 分页, offset, 返回顺序, 扫描方法原理(seqscan, index scan, index only scan, bitmap scan...

标签PostgreSQL , 数据离散性 , 扫描性能 , 重复扫 , bitmap index scan , 排序扫描 , 扫描方法 , 顺序背景一个这样的问题:为什么select x from tbl offset x limit x;两次查询连续的OFFSET,会有重复数据呢?select ctid,* from tbl where ... offset 0 limit 10;select ...

weixin_39695954的博客 881

人大金仓数据库Hint指定扫描方式

Scan类型的Hint是指明单表扫描时在目标表上使用特定的扫描方法。它只会在普通表、继承表、UNLOGGED表、临时表和系统目录上生效。外部表、表函数、VALUES子句、CTE、视图和子查询不受影响。其括号内的值只能是一个表名。但可以在一个查询中,对其中的多个目标表进行不同方式的干预。具体类型及对应的描述如下:Hint类型描述优先在表上使用顺序扫描优先在表上使用Tid扫描优先在表上使用[指定的]索引扫描优先在表上只扫描索引列(Index Only Scan)

arthemis_14的博客 1185

PostgreSQL查询的扫描方式

【代码】PostgreSQL查询的扫描方式。

sig321的专栏 1152

PostgreSQL 定位索引损坏位置

摘要:通过SQL检查发现索引"idx_name"存在不一致问题,报错显示两个记录的索引顺序违反规则。使用有问题的TID查询实际数据时,发现两条记录(0091tv.com和009-1tv.com)在编码后存在差异(3030393174762e636f6d vs 3030392d3174762e636f6d),这可能是导致索引错误的原因。

情深深几许 200

【PostgreSQL】执行计划、常用命令

取某表随机值。 数据加压。 取表的列信息

dreambyday 2323

PostgreSQL · 最佳实践 · EXPLAIN 使用浅析(优化器,查询计划)

PgSQL · 最佳实践 · EXPLAIN 使用浅析 背景 在使用数据库时,经常会有开发者有这样的疑问:“我的表对应字段已经创建了索引,为什么这个SQL 语句执行还是这么慢?” 虽然数据库SQL 执行慢有很多原因,但是对于PostgreSQL DBA 来说,好像有个共识,遇到用户慢SQL优化的问题,先拿EXPLAIN 命令查看下对应的查询计划,从而可以快速定位慢在哪里。这就引出了本文的主角—PostgreSQL 的EXPLAIN 命令。 EXPLAIN 语法 在PostgreSQL 中,EXPLAIN 命

荷塘月色 6961

greenplum seq acan 和 index scan

set session enableseqscan=false; # 默认是true,查询非常少量的数据是有效 下面sql设置为false是true效率6倍 、select dtype,name from ambmaccnt where statdate =20170701 group by dtype,name limit 100...

qq_36748772的博客 965
上一篇: PostgreSQL 性能:云端与本地的延迟分析
下一篇: PostgreSQL 18 RETURNING 增强:现代应用的重要进展
IvorySQL
博客等级 码龄5年 745粉丝 566原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值