行情系统越用越慢?从数据治理到索引缓存的性能优化实践
如果你是做行情系统的某天运营跑过来跟你说最近行情页越开越慢数据也经常卡住你大概会先怀疑网络再怀疑客户端最后才不情不愿地把目光转向自己的后端。但真实情况往往是网络没问题、客户端没问题、数据库也没报错可系统就是肉眼可见地变慢了。这个越做越慢的过程不是某一次上线引入的故障而是随着数据累积、业务迭代、架构妥协一点点沉淀下来的。我这几年代运维、做优化在行情类系统上踩了不少坑今天把排查思路和落地优化整理成文希望能帮你少走点弯路。行情系统有个很特殊的地方它不是用的人多了才慢而是数据多了就慢。用户的并发量可能一直很平稳但行情数据是持续滚动写入的日积月累查询路径上的每一个环节都会被数据量放大。慢是必然的好在你只要搞清楚它到底慢在哪一层就有办法把它拉回来。1. 行情系统变慢的信号先分清是哪一种慢1.1 用户感知到的慢未必是后端的锅接到行情变慢的反馈第一件事不是查数据库而是先复现并确认用户说的慢到底是哪一种。我一般会先分三类。第一类是首屏打开慢比如客户端从启动到第一根K线渲染出来要好几秒这通常是初始化接口慢、前置资源加载重、或者网关路由配置拖了后腿。第二类是实时刷新卡顿比如行情跳动不流畅、分时图一卡一卡的这往往是推送链路的问题跟WebSocket连接数、推送频率、客户端渲染能力都有关系。第三类是查询响应慢比如查某只股票的历史分笔、查某段时间的分钟线转圈圈转很久才出数据这才和数据库、缓存、接口逻辑直接相关。很多团队一听到慢就扎进SQL优化里结果查了半天发现慢的是首页加载了一堆没必要的行情列表。所以先别急着动手给慢分好类再决定往哪个方向排查。我的经验是第一类和第三类最容易混在一起一定要先看现象是集中在首次访问还是每次访问。1.2 服务端指标上的慢比用户反馈更早暴露问题用户反馈是滞后的系统指标才是实时的。行情系统越做越慢通常会在监控图上提前露出马脚。你需要盯几个关键指标接口P99响应时间是不是在逐周缓慢上升数据库慢查询数量是不是从每天几十条涨到每天几千条Redis命中率是不是在往下掉行情推送的WebSocket连接数是不是涨了一倍而机器负载没降。这些指标单独看可能都不算事故但把它们拉到三个月的时间轴上对比就能看到一条清晰的恶化曲线。我最常用的做法是搭一个简单的趋势看板把核心接口的响应时间、数据库慢查询数、缓存命中率、GC暂停时间这几项按天聚合每周瞄一眼。行情类的系统特别适合这种趋势发现的思路因为它不是突发故障而是渐进劣化。等你从用户反馈里感知到慢的时候监控曲线通常已经爬了两三个月了。2. 根因拆解行情系统为什么越跑越重2.1 数据只进不出存储积压成山行情系统的数据特征是高频、海量、持续写入。每一笔成交、每一条快照、每一次五档盘口变化都会落库。刚开始一天几百万条分页查询随便加个索引就很流畅等跑了一两年单表几个亿甚至几十亿条原来好用的SQL开始超时原来秒开的页面开始转圈。这就是最典型的第一重原因数据只进不出存储层被时间堆满了。很多团队在设计初期没有制定归档策略觉得反正磁盘够大先存着。等到数据量上来你会发现磁盘其实也扛得住扛不住的是索引膨胀和查询扫描范围。一张十亿行的表即使命中索引B树的层数和随机IO也会让延迟明显上升更别提有些查询条件设计得不好根本没法走索引全表扫描一动就是几十秒。提示行情数据是典型的时序数据永远只查最近一段时间是常态。如果你们还在用关系型数据库存全量行情且没有归档机制那慢只是时间问题。2.2 索引和表结构没跟着数据形态一起进化第二个高频根因是索引设计停留在系统上线初期。项目刚起步时数据量小随手加几个索引就能跑。等数据量上来当初的索引可能不再是查询的最优路径甚至成了写入的负担。举几个我实际见过的例子联合索引的字段顺序跟现在的查询条件不匹配导致索引失效MySQL只能走全表扫描。针对查最近N条这种高频查询没有设计倒序索引或覆盖索引每次查询都要先排序再返回排序的数据量一大就慢。行情明细表按时间建的索引但业务侧经常按股票代码时间范围查询索引的最左前缀用不上。分表方案是按股票代码哈希拆的但运营后台经常按时间维度跨全表统计一次统计把所有分表扫一遍。这些问题在数据量小的时候都是能跑就行但在行情系统里数据量增长是确定的、持续性的所以索引和表结构必须跟着数据的增长节奏定期复盘。我见过不少团队优化一次之后一两年不再碰索引设计系统自然越来越慢。2.3 缓存策略从加速器变成拖累行情类系统几乎离不开缓存Redis、本地缓存、CDN都会用。但缓存用不好反而会加剧变慢。最典型的场景是缓存穿透。比如查询某只停牌股票的历史数据缓存里没有数据库里也没有每次请求都直接打到数据库。平时流量低没感觉一旦行情波动大用户疯狂刷新数据库瞬间就被穿透流量打满。还有缓存击穿和缓存雪崩。击穿是某个热点key比如某只暴涨的股票在缓存过期的一瞬间大量请求同时打到数据库雪崩是大量key在同一时段过期数据库压力陡增。这两种情况在行情系统里尤其常见因为热点标的的访问量高度集中且客户端经常在整点或开盘瞬间集中刷新。另一个容易被忽视的问题是本地缓存与Redis之间的数据一致性。行情数据更新极快如果本地缓存没有合理的过期时间或版本控制用户看到的行情可能滞后几秒甚至几分钟。为了实时性而把缓存全去掉也不行那会让数据库直接被查询流量打垮。缓存策略需要在这种矛盾里找平衡。2.4 高频更新场景下的GC与锁竞争行情系统的后端服务往往是高并发、低延迟的推送型服务这种场景对JVM的GC非常敏感。如果服务用Java编写且长期处理高频行情推送GC问题会随着时间推移越来越明显。常见的情况是行情对象在堆里堆积老年代持续增长Full GC频繁触发每次Full GC都会造成毫秒到秒级的停顿。对普通接口来说几百毫秒的停顿可能无感但对行情推送来说一次停顿就意味着几百上千条推送滞留恢复后集中补推又会造成新一轮的压力。还有锁竞争。热点股票的数据更新非常频繁如果代码里用全局锁保护共享缓存或者同步块范围过大多个线程同时更新同一只股票的快照时就会互相阻塞。线程一多锁等待的时间占比上升接口延迟就会肉眼可见地增长。这些属于代码和运行层面的问题不会像数据量那样线性增长但它们会在系统负载上升时被放大表现得就像系统突然慢了很多。3. 实操排查从现象到根因的完整步骤3.1 先做链路梳理别一头扎进数据库排查变慢问题我最忌一上来就开慢查询日志。第一步应该是把一条行情请求的完整链路画出来从客户端发起、网关转发、鉴权、业务处理、缓存读取、数据查询到结果返回每一跳都标注耗时。这个环节不需要复杂工具用链路追踪中间件或者简单地打日志打印每一跳的时间戳就能完成。如果是老系统没有埋点可以先在网关和核心服务入口各打一条日志先确认慢的是在网关层还是业务层。我遇到过一个案例接口P99从200ms涨到800ms排查了半天数据库后来发现是网关层对某个接口做了额外的限流排队请求都在网关排队等令牌。链路梳理不做的代价就是你可能在一个错误的方向上耗费大量时间。注意链路梳理时不要只测一条链路。行情系统往往存在多种查询模式——实时快照、历史K线、分笔明细、批量列表——各自的瓶颈可能完全不同需要分别梳理。3.2 打开慢日志和慢查询分析确认数据库层面确实存在慢查询之后再打开慢日志。MySQL的慢日志配置比较简单在my.cnf里设置slow_query_logON和long_query_time1然后观察一段时间收集慢SQL样本。拿到慢SQL之后不要急着改SQL先用EXPLAIN看执行计划。重点看三样东西是否走索引、扫描行数、是否出现临时表和文件排序。我经常看到的问题SQL有两类。一类是查询条件里对索引列做了函数运算比如WHERE DATE(create_time) 2024-01-01索引直接失效另一类是ORDER BY字段不在索引里导致每次查询都要做文件排序。这两类问题在数据量不大的时候表现不明显一旦数据涨上去响应时间几乎是指数级变差。3.3 拆解缓存命中率与热点分布如果数据库层面没有明显问题下一步看缓存。行情系统的缓存设计通常分几层接口层的本地缓存、共享层的Redis、页面层的CDN。每一层都有命中率指标把每一层的命中率拉出来看基本就能定位到是哪一层出了问题。Redis的INFO stats里可以直接看keyspace_hits和keyspace_misses算出命中率。如果命中率持续较低就要检查缓存Key的设计是否合理、过期时间是否设置得过短、是否有大量不可缓存的动态查询。还可以用Redis的--hotkeys参数或者MONITOR命令临时观察热点key分布。行情系统里少量热点股票的访问量可能占到总量的八九成这类key必须单独设计缓存策略。3.4 定位线程阻塞与GC问题Java服务出现变慢时jstack和jstat是你最好的两个工具。jstat -gcutil pid 1000可以连续观察GC情况。如果看到老年代的使用率持续高位、Full GC频繁且耗时长基本可以确定GC是元凶之一。这时候用jmap导出堆转储配合分析工具查看是哪些对象占用了大量内存。线程阻塞的问题用jstack抓线程快照重点看WAITING和BLOCKED状态的线程分布。如果大量线程阻塞在同一个锁或同一个对象上去代码里找对应的同步块十有八九能发现锁粒度的问题。行情数据的更新和读取如果共用一把锁读多写多的情况下会让吞吐量直线下降。4. 优化落地一套可复用的改进方案4.1 数据治理归档、分区与冷热分离只要行情系统还在持续运行数据就会持续增长。所以第一步优化永远是数据治理而不是所谓的高性能SQL技巧。我推荐的做法是三层推进。第一层是制定归档策略历史行情数据超过一定时间比如一年或两年的定时迁移到归档表或大数据平台业务查询默认只访问热数据表。第二层是表分区行情明细表按时间做RANGE分区比如按天或按月分区查询时自动裁剪到对应分区扫描数据量能小一个量级。第三层是冷热分离高频访问的近期数据放在高性能存储上低频访问的旧数据放到廉价的冷存储。实际经验是分区表带来的收益往往比加索引更立竿见影。比如一张按天分区的行情表查询某只股票最近三天的分钟线只需要扫三个分区而不是扫全表。配合归档策略业务库的数据量能控制在一个稳定的水位查询延迟也就不会随着时间持续恶化。4.2 查询优化重建索引与SQL改写数据治理解决的是数据太多的问题索引优化解决的是查得不够快的问题。索引重建的前提是搞清楚业务最核心的查询模式。行情系统里最高频的无非这么几类按股票代码查最新行情、按股票代码时间范围查K线、按时间段查全市场列表。针对每一类查询设计单独的联合索引索引字段的顺序按照等值条件在前、范围条件在后、排序列尽量包含的原则来排。SQL改写方面有几个实用手法。一是避免在索引列上使用函数或隐式转换比如时间条件写成create_time ? AND create_time ?而不是DATE(create_time) ?。二是用覆盖索引减少回表如果查询只需要少数几个字段把这几个字段都放进索引里。三是分页优化深分页用游标或者基于上次查询的最后一条记录来翻页而不是LIMIT 100000, 20这种暴力跳页。提示加索引不是多多益善。每个索引都会拖慢写入速度行情系统的写入量又特别大所以索引必须精简一个索引服务一类高频查询用不到的索引及时删。4.3 缓存与推送架构的调整缓存优化的核心是针对前面提到的穿透、击穿、雪崩问题做防御同时和推送架构结合让数据足够新鲜。穿透的防御手段简单直接对缓存和数据库都不存在的数据在Redis里缓存一个空值并设置较短的过期时间或者在接口层用布隆过滤器快速判断不存在的Key直接拦截掉。击穿的防御是热点Key永不过期或逻辑过期热点数据用单独的逻辑异步刷新而不是等缓存过期了再去数据库读。雪崩的防御是过期时间加随机值让大量Key的过期时间错开。行情推送这块我的建议是推送为主、缓存为辅。实时行情优先通过WebSocket推送让客户端拿到增量数据查询接口更多承担初始化拉取和兜底职责。这样可以把高频查询压力从数据库和缓存链路里卸掉一大半系统的整体容量能上一个台阶。推送链路本身要关注连接数管理、心跳保活和消息积压指标避免连接数失控导致内存暴涨。4.4 代码层与JVM层面的调优GC问题的优化方向是减少对象分配和缩短对象存活时间。行情对象尽量复用避免每次推送都new一批对象快照数据用池化或预分配的方式管理缓存对象设置合理的过期时间避免大量数据长期滞留在老年代。如果确认Full GC频繁可以调整JVM参数。比较实用的做法是适当调大新生代比例让短生命周期的行情对象在新生代就被回收不进入老年代同时用G1收集器设置合理的MaxGCPauseMillis目标。锁竞争的优化核心是缩小锁范围。把更新整只股票快照改成更新快照里的单个字段级别的细粒度锁或者用原子数据结构配合CAS操作代替锁。行情系统的很多场景其实是单线程模型更合适比如单只股票的行情更新放在一个独立的线程队列里顺序处理完全避开锁竞争。注意JVM参数也好线程模型也罢改动之前一定要做压测对比。行情系统对延迟敏感有时候参数看起来更标准了实际表现反而变差。任何调优都要用数据说话。5. 踩坑记录与排查技巧实录5.1 常见问题速查表下面是我在实际排查中遇到频率最高的问题和对应解法整理成一张速查表方便你遇到类似现象时快速对照现象可能原因排查手段解决方案查询最近行情越来越慢单表数据量过大无归档查看表行数与慢日志按时间分区归档策略特定股票详情页卡顿索引失效或没命中EXPLAIN查看执行计划重建索引、SQL改写行情波动时段数据库CPU飙高缓存穿透/击穿查看Redis命中率空值缓存、逻辑过期、布隆过滤器推送消息延迟、积压WebSocket连接数失控监控连接数与积压量连接数上限控制、心跳优化服务频繁卡顿数秒Full GC频繁jstat观察GC情况JVM参数调整、对象复用并发上升后响应时间暴涨锁竞争严重jstack查看线程状态细粒度锁、单线程队列模型冷启动后首次访问特别慢缓存未预热检查缓存击穿日志启动预热、预加载热点数据5.2 几次让我印象深刻的真实排查有一次某套行情接口的P99从300ms涨到1.5秒持续了将近两周没人发现直到用户投诉才拉响警报。我查了半天发现根因是三个月前一次业务迭代把查询条件从股票代码时间改成了股票代码列表时间原来的联合索引最左前缀失效数据库一直在走全表扫描。这个问题在列表只有几十个股票的时候不明显等列表扩大到几百个扫描量直接翻了几十倍。还有一次是典型的缓存雪崩。某天开盘后所有股票的缓存Key在同一时间过期数据库瞬间被打满行情查询大面积超时。排查发现缓存过期时间写死成了一个固定值没有加随机扰动。修复方式是用固定间隔加随机偏移问题当天就消失了。这两次经历让我养成一个习惯每次做业务迭代都要把涉及的数据访问模式重新过一遍索引和缓存策略要跟着迭代走而不是上线就完事。5.3 预防性手段怎么避免越做越慢变慢是可以预防的关键在于把性能治理纳入日常的迭代流程里而不是等出了问题再去排查。我建议做三件小事。第一每周看一次核心接口的性能趋势把P99、慢查询数、GC次数记下来画个趋势图。连续三周往上走就该主动排查了。第二每次上线涉及查询逻辑变更必须带EXPLAIN执行计划评审数据量假设按未来一年的规模评估。第三建立定期压测机制每季度做一次全链路压测用未来半年的数据量预估做压测水位提前暴露容量瓶颈。这三件事看起来简单但很多团队就是不做结果系统是在一次次的被动救火中慢慢劣化的。行情系统尤其如此数据增长是确定的性能劣化也是确定的唯一不确定的是你什么时候正视它。最后分享一点个人体会。行情系统变慢从来不是单一原因造成的它更像一个慢性病是数据膨胀、索引失效、缓存设计、代码质量、架构演进等多个因素叠加的结果。每一次只解决单个问题看起来都是在救火但真正的思路应该是定期给系统做体检把性能治理当成运维的一部分。踩过几次坑之后你就会发现行情系统最需要的是预见性在数据量和业务复杂度还没压垮系统之前就提前把架构和策略调整到位。这也是我从一个被动修Bug的人慢慢变成主动做优化的过程中最大的感悟。

相关新闻

PHP短网址系统核心实现:短码生成、伪静态与跳转实战

PHP短网址系统核心实现:短码生成、伪静态与跳转实战

简介:一份基于PHP开发的黑色简洁短网址生成系统源码,面向需要自建短链接服务的个人站长、开发学习者。前端提供了URL创建、自定义别名、密码保护、链接统计、暗色主题、小书签以及复制与共享链接等功能,交互简洁;后端支持网址删除…

2026/10/18 9:06:25 阅读更多 →
Chrome安装Axure插件:解决file协议下原型预览交互失效

Chrome安装Axure插件:解决file协议下原型预览交互失效

简介:面向Axure原型设计师的Chrome扩展插件,最新版本0.6.3.0,下载解压后即可直接安装使用,不需要复杂配置。它把Axure的设计能力延伸到浏览器中,支持实时预览原型项目、快速捕获网页设计灵感、提取颜色/字体/图标等元素…

2026/10/18 9:05:25 阅读更多 →
论文写作工具怎么用:从辅助到合规的高效流程指南

论文写作工具怎么用:从辅助到合规的高效流程指南

最近后台和私信里问得最多的就是论文工具,尤其是周围学生圈子里都在讨论的“千笔写作工具”,标题里动不动就是“一键生成论文”“省心了”这类词。我第一反应不是兴奋,而是有点担心——担心大家对这个工具的理解跑偏了。这篇就围绕千笔写作工…

2026/10/18 9:05:25 阅读更多 →

最新新闻

Git多人项目开发流程实战:分支模型、代码评审与冲突处理

Git多人项目开发流程实战:分支模型、代码评审与冲突处理

很多同学学会 Git 的第一天,基本都是从git commit和git push开始。一个人写仓库怎样都好说,今天merge明天rebase,大不了reset回滚,反正卷宗里只有自己一个人,怎么折腾都有救。可一旦进入“Git 多人项目开发流程演练”的…

2026/10/18 18:00:49 阅读更多 →
2026马德里AIW 2026:人工智能与机器人展观展要点

2026马德里AIW 2026:人工智能与机器人展观展要点

每年年初我都会习惯性打开欧洲几个主要展会的官网,把一年的行业安排提前圈出来。2026年这一轮,最让我留意的不是巴塞罗那的通信展,也不是汉诺威的工博会,而是马德里这场名字听起来还不算太响的专业展会:2026年西班牙马…

2026/10/18 18:00:49 阅读更多 →
HTML+JS+CSS+jQuery实现高兼容性音乐播放器

HTML+JS+CSS+jQuery实现高兼容性音乐播放器

1. 这不是炫技Demo,而是一个能真正在浏览器里跑起来的音乐播放器“HTMLJavaScriptCSSJQuery实现音乐播放器”——看到这个标题,很多人第一反应是:又一个课堂作业?或者某次前端入门练习?但如果你真把它当成练手小项目随…

2026/10/18 18:00:49 阅读更多 →
IconFont图标库实战:从选型到性能优化的完整指南

IconFont图标库实战:从选型到性能优化的完整指南

1. 从一堆散落图标说起:为什么我最终选了IconFont图标库做前端或者客户端开发的人,几乎都绕不开图标这件事。一个页面里,返回箭头、搜索放大镜、购物车、用户头像、设置齿轮,这些视觉元素看着不起眼,但真到落地的时候&…

2026/10/18 18:00:49 阅读更多 →
只靠检测保食安,是个伪命题

只靠检测保食安,是个伪命题

《只靠检测保食安,是个伪命题》 ——安全不是查出来的,是接出来的过去十年,食品安全靠的是罚单;未来十年,靠的是数据。先看一个反差。全国食品抽检合格率,多年稳定在百分之九十七以上,连年向好。…

2026/10/18 18:00:49 阅读更多 →
UE5 C++字符串与容器全解析:FString、FName、FText与TArray、TMap底层原理

UE5 C++字符串与容器全解析:FString、FName、FText与TArray、TMap底层原理

做 UE5 C 开发,容器和字符串这两块绕不过去。项目做大了,每次新建一个类、存一份配置、调一次接口,都要跟它们打交道。我最早是从 std 那套东西切过来的,一开始真被 UE 的命名搞晕过——明明都是字符串,为什么有 FStri…

2026/10/18 17:59:49 阅读更多 →

日新闻

基于GMM的语音识别系统原理与MATLAB实现详解

基于GMM的语音识别系统原理与MATLAB实现详解

说到基于高斯混合模型(GMM)的语音识别系统,很多人第一反应就是一堆数学公式,觉得门槛很高。但如果你真的在MATLAB里把它落地跑通,会发现核心其实就是三件事:把声音变成特征向量,用GMM给每个类别…

2026/10/18 0:00:55 阅读更多 →
数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理这四个字听起来挺唬人,但落到具体操作上,无非就是让计算机按你的想法“摆弄”像素。我在一个模拟项目X里用了一套特别经典的基础处理流程:对图像做反白、改调色板、彩色转灰度,最后把像素数据导出成txt文件。单看每一…

2026/10/18 0:00:55 阅读更多 →
机器人大脑技术盘点:具身智能的感知、决策与数据闭环

机器人大脑技术盘点:具身智能的感知、决策与数据闭环

如果你的信息流最近也天天刷到“机器人大脑”这个词,你会发现一个很有意思的现象:每个人说的“大脑”根本不是同一个东西。有人指的是大语言模型,有人指的是运动控制系统,还有人指的是能理解物理世界的端到端模型。在2026年这个时…

2026/10/18 0:00:55 阅读更多 →

周新闻

基于GMM的语音识别系统原理与MATLAB实现详解

基于GMM的语音识别系统原理与MATLAB实现详解

说到基于高斯混合模型(GMM)的语音识别系统,很多人第一反应就是一堆数学公式,觉得门槛很高。但如果你真的在MATLAB里把它落地跑通,会发现核心其实就是三件事:把声音变成特征向量,用GMM给每个类别…

2026/10/18 0:00:55 阅读更多 →
数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理这四个字听起来挺唬人,但落到具体操作上,无非就是让计算机按你的想法“摆弄”像素。我在一个模拟项目X里用了一套特别经典的基础处理流程:对图像做反白、改调色板、彩色转灰度,最后把像素数据导出成txt文件。单看每一…

2026/10/18 0:00:55 阅读更多 →
机器人大脑技术盘点:具身智能的感知、决策与数据闭环

机器人大脑技术盘点:具身智能的感知、决策与数据闭环

如果你的信息流最近也天天刷到“机器人大脑”这个词,你会发现一个很有意思的现象:每个人说的“大脑”根本不是同一个东西。有人指的是大语言模型,有人指的是运动控制系统,还有人指的是能理解物理世界的端到端模型。在2026年这个时…

2026/10/18 0:00:55 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/18 0:55:02 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/17 17:22:31 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/18 12:16:16 阅读更多 →