# 领星统计查询性能优化方案 面向平台销售开发总控,当前先完成功能、真实数据正确性及人工页面确认,并发优化后置。本文维护后续性能专项规划,不触发代码修改、真实采集或压测,不把新增诊断任务变成功能联调的前置条件;页面不可用、请求超时或数据错误仍按功能问题处理。 性能专项恢复时,按“复用完整基线与诊断 → 验证有证据的新候选 → 全场景验收”推进。窄投影、profile 归并和延后商品名称均已试验,未显示稳定收益,移出默认实施顺序;只有新的执行计划证据表明问题或条件发生实质变化时才考虑重测。每次只验证一项主要改动,保留结果一致性与执行计划证据。 本文为 2026-10-13 的查询优化执行方案,只交付文档,不修改代码或操作环境。业务口径、版本保护及验收目标继续以[一期主方案](领星一件代发数据统计一期方案.md)和[经营总览图表设计](经营总览图表设计.md)为准;本文不另建部署状态或验收进度台账。开发安排由[平台销售总控](codex://threads/01a12feb-0474-77f1-afe0-a3b491733dca)统一收口。 用户本轮追加的领星获取速度、重复请求与等待开销只读梳理,统一维护在[采集速度优化顺序](#采集速度优化顺序)。它与前述经营查询 SQL 优化分开,不因本次梳理调整正在运行的采集任务或提高账号出口并发。 ## 对照基线与问题判断 以[库存索引倒序优化后的完整压测](../../baiyue-firstleg/reports/selfop-test-20261013/selfop-perf-read-r5-inventory-seek-r2-result.json)为本次核对取得的较新基线。该轮于北京时间 2026-10-13 10:29 结束,合成数据共 11,968,200 条 SKU 日行,包含多个版本;不能把这个总量当作单仓单版本行数。10 个并发用户持续约 301 秒,总览和销量各完成 664 次、默认库存完成 663 次,共 1,991 次,无请求错误。 | 查询路径 | P50 | P95 | P99 | 现行 P95 目标 | | --- | ---: | ---: | ---: | ---: | | 经营总览近 15 天 | 2,732 ms | 3,107 ms | 3,275 ms | ≤1,500 ms,未达标 | | SKU 销量近 15 天 | 1,150 ms | 1,382 ms | 1,489 ms | ≤1,000 ms,未达标 | | 默认库存列表 | 613 ms | 774 ms | 849 ms | ≤1,000 ms,该场景达标 | [此前仓库日汇总后的报告](../../baiyue-firstleg/reports/selfop-test-20261013/selfop-perf-read-r5-warehouse-daily-r1-result.json)中,三个路径的 P95 分别为 3,169、1,412、1,092 ms。保留它作为前后对照,不能继续将默认库存写成尚未达到 1 秒,也不能把默认列表通过扩大为所有关注筛选、排序和下钻均已通过。 常用路径稳定性通过不代表完整性能验收通过。该压测报告仍列有未验证项;后续[分段诊断摘要](../../baiyue-firstleg/reports/selfop-test-20261013/selfop-query-timing-r4-summary.json)补充了 SQL 次数与阶段耗时采样,不能再把这项写成完全未开始。后台候选构建并行、构建增长成本、复杂筛选及原单增长不影响查询等仍需专项证据。旧销量版本的 366 天 SKU 清单在较早报告中有约 7.30/7.39 秒的单次抽样,后续需复核;单次结果不能当作 P95。 已完成且输入条件一致的基线与诊断直接复用,中途停止的压测不算完整基线。恢复性能专项后,先核对期间功能修复是否改变查询 SQL、索引、数据集、版本和资源条件,再决定是否需要更新基线,不因本文更新原样重跑。以上为固定证据快照,后续实际部署和验收状态仍由现行主契约维护。 ## 保留已有优化 当前代码已具备以下能力,不再作为待从零实现的任务: | 已有能力 | 代码入口 | 本轮处理 | | --- | --- | --- | | 趋势读取已发布仓库日汇总,进入查询前验证就绪证据 | [DashboardReadMapper](../../baiyue-firstleg/lastleg-service/src/main/java/com/baiyue/lastleg/selfoperated/analytics/query/DashboardReadMapper.java)、[DashboardQueryService](../../baiyue-firstleg/lastleg-service/src/main/java/com/baiyue/lastleg/selfoperated/analytics/query/DashboardQueryService.java) | 保留,不再让趋势扫描所有 SKU 日行 | | 一次 report 返回统计和三个 Top 10,共享 SKU 计算结果 | [DashboardReadSql](../../baiyue-firstleg/lastleg-service/src/main/java/com/baiyue/lastleg/selfoperated/analytics/query/DashboardReadSql.java) 的 `report` | 保留共享计算,不拆成每张图独立扫描;窄投影按下文已试验结论处理 | | 默认库存按库存量先选页,再补该页销量;普通 ALL 计数只读候选身份 | [AnalyticsInventorySql](../../baiyue-firstleg/lastleg-service/src/main/java/com/baiyue/lastleg/selfoperated/analytics/query/AnalyticsInventorySql.java) 的 `stockFirst`、`inventoryCount` | 保留轻量路径,不能被复杂筛选的通用方案拖慢 | | 默认库存最后出库日按现有索引倒序取首条 | 同上 `inventoryPage` | 复用上文已完成的并发结果;仅默认 ALL+AVAILABLE_DESC 且无分桶/selection 的路径已采用,复杂筛选不能视作同时完成 | | SKU 销量清单先选分页键,再计算本页完整/部分/未知日数 | [AnalyticsReadSql](../../baiyue-firstleg/lastleg-service/src/main/java/com/baiyue/lastleg/selfoperated/analytics/query/AnalyticsReadSql.java) 的 SUMMARY 分支 | 保留,不重新引入所有 SKU × 所有日期的展开 | | 库存过期或 30 日不完整时,总览跳过相应无用事实聚合 | `AnalyticsInventorySql.dashboardCte` | 保留,不能以资格不足场景的快速结果代替完整场景验收 | 查询已经有日表覆盖索引,不能仅凭慢就继续叠加相近索引。最多 366 个趋势点、30 条榜单记录的 Java 处理暂不列为优化重点。 ## 复用分段诊断并限定剩余测量 分段诊断共 39 个请求,包含三个接口各 3 个单用户样本和各 10 个并发样本;它明确标为诊断用途、非 P95 验收。并发组的已观测结果如下,均为平均值: | 路径 | 主要 SQL 阶段耗时 | 其他阶段与结论 | | --- | ---: | --- | | 总览 | report 约 3,028 ms | context 约 4 ms、daily 约 2 ms;优先研究全仓 SKU 聚合、分桶及榜单成本 | | SKU 销量 | page 约 1,166 ms | count 约 54 ms、context 约 4 ms;优先研究区间聚合与分页排序 | | 默认库存 | page 约 498 ms | count 约 48 ms、context 约 5 ms;保留已达标路径,后续做回归 | 三个接口在这组样本中均固定为 6 条统计读 SQL。诊断范围为 `ONLY_ANALYTICS_READ_MAPPERS`,不能将 6 条说成包含 IAM/鉴权等全部应用 SQL,也不能由小样本推断全部场景都不存在额外调用。采样已指出主要 SQL 成本;连接池等待、数据库资源竞争、写入重叠等仍按需要补证据,不再从头重复同一诊断。 固定同一数据集、代码版本、仓库、双统计版本、业务日期、覆盖证据和库存时效,分别记录以下阶段。跨午夜、库存过期、版本切换或测试数据重建后,需要重建可比基线。 | 请求 | 需要分开的耗时 | | --- | --- | | 总览 | 权限与 context 校验、仓库 daily、report、DTO 组装、序列化与 HTTP 总耗时 | | SKU 销量 | context、候选 count、分页及日量聚合、DTO/HTTP | | 库存 | context 与下钻资格、count、分页与最后出库日、DTO/HTTP | 每个代表 SQL 保存绑定参数范围、执行计划、实际行数/循环数/耗时、排序和临时表证据。对比 profile、snapshot、daily 各访问节点,确认共享 CTE 是否确实只构建一次。同一请求关联各阶段耗时,不能用两个阶段各自的 P95 相减估算成本。数据库总耗时还应与连接池等待、CPU、磁盘及同机负载对照,不能把 HTTP 与数据库耗时之差全部归给 Java 计算。 只采集当前测试需要的只读诊断;`EXPLAIN ANALYZE` 会真正执行查询,沿总控既有环境窗口安排,不和另一轮压测或构建竞争。诊断参数采用合成账号和业务编码,不在文档、日志或证据中写凭据及真实客户载荷。 候选方案先做相同输入的响应对照,再做单请求 SQL 对照;有一致且可解释的收益,才进入整轮 HTTP 压测。首次应用请求、预热和业务结果缓存命中分别标注,不把“首次应用请求”称为数据库磁盘冷启动;不为制造冷启动清理共享数据库缓存。 ## 已试验方案与重试条件 依据[开发总控 2026-10-13 的后续性能反馈](codex://threads/01a12feb-0474-77f1-afe0-a3b491733dca),以下三项已经测试,均未显示稳定收益。此处记录试验结论与选题边界,不把“尚无稳定收益”扩大成所有数据规模下永久无收益,也不编造提升比例。 | 方案 | 已有结论 | 默认处理 | 重新验证的前提 | | --- | --- | --- | --- | | 总览共享结果窄投影 | 已试验,未显示稳定收益 | 不再列为首选任务,不重复原样 A/B | 新执行计划显示宽字段确实造成主要临时表/去重成本,且能说明新方案与已测方案的实质差异 | | 两版 profile 归并以减少重复访问 | 已试验,未显示稳定收益 | 不再安排同一归并方案 | 新执行计划显示 profile 访问成为主要成本,并能指出访问路径、规模或归并方法相对既有试验发生的变化 | | 榜单确定后延后读取商品名称 | 后续已试验,未显示稳定收益 | 从待试新候选中移除,不再单独派工 | 新证据表明名称访问或携带名称的中间结果成为主要成本,且处理方式与已测方案存在实质差异 | 重试前先复用总控保留的代码版本、输入及计划证据,写清旧结论、新证据和本次差异。重新发布文档、换一个试验名称或重新出现同一静态代码建议,都不构成重试理由;已有试验详细证据需要核对时先核对记录,不直接重跑。 若满足上述前提,正确性边界仍保留:窄投影不能删除身份、分类、资格或排序所需字段,观察证据即使不展示也须参与上游计算;profile 归并须保留来源存在标记,区分“无该版记录”和“该版字段无效”,不能因 MAX/MIN 忽略空值而将未知改成有效。单位资格、编码比较、名称优先级及有效观察依据均不变,库存过期也不意味着其 profile 身份可删除。 ## 后续集中处理两条主要慢查询 ### 总览聚合与销量分页 总览以 report、销量以 page 为下一阶段的主要优化对象。对照已有计划核实日行扫描、聚合、排序及物化的实际工作量,先说明新方案具体减少哪一部分,而不是继续围绕已无收益的字段/名称调整。默认库存保留回归覆盖,不继续作为主要提速目标。 总览固定 30 日的重复计算与销量清单任意日期区间是两种需求,不能用只覆盖固定 30 日的结果替代今日、近 3 天、本周、近 15 天、本月及历史自定义区间。若要评估把重复计算移到版本构建阶段,按后文条件分支测算读取收益和构建成本,另行形成具体设计,不直接追加统计表。 连接池或线程数只有在等待和资源证据支持时才评估,不以增加请求并行度代替减少数据库工作量。每项候选均保留固定版本、全候选资格、未知值及排序语义,不提前裁掉 SKU 获得表面速度。 ### 按实际成本审视物化方式 `DashboardReadSql.report` 的 DISTINCT 有阻止四个消费者重复展开计算的用途,不能直接删除。如果新的分段与执行计划证据显示共享结果的去重仍是主要成本,再核对既有试验,决定是否有值得验证的物化替代方案;不把 `NO_MERGE` 等提示自动当作尚未尝试的新方向,也不要求先重做窄投影。 任何替代方案都要证明统计与三个榜单仍共用一次聚合,没有将 daily/snapshot/profile 展开四次。计划不稳定或未显示可重复收益时,保留当前实现;不能仅凭提示写进 SQL 就认定生效。已试验方案若无实质变化,直接沿用既有结论。 ## 减少复杂库存筛选的重复聚合 `AnalyticsQueryService.inventoryCoverage` 先调用 `inventoryCount`,再读取 `inventoryPage`。当条件依赖销量资格,例如无销量、可售天数、分桶或无法评估时,两次查询都会执行相近的完整候选计算。 分段测量若证实这两次聚合是相关路径的主要成本,再尝试一次共享候选:先在全候选上计算、筛选和排序,再从同一结果取得计数与当前页。执行计划须证明公共聚合只执行一次,仅抽取相同 SQL 字符串再调用两次不算共享。统计行应独立产生,即使结果为空或 offset 超出末页也返回真实 total,并且不能把统计占位行映射成伪 SKU 记录;不能仅依赖附在页记录上的 `COUNT(*) OVER()`,否则空页会丢失总数。响应 DTO 继续使用现有分页合同,不对前端引入第二套格式。 必须保留普通 ALL 的身份计数、冻结/次品关注的库存专用计数,以及默认库存先分页方案。**本项主要优化图表下钻和复杂筛选,不承诺降低基线中的 inventory-ALL 耗时。** 复杂筛选最后出库日仍可单独评估同一 SQL 内的页内索引倒序探测;它只补充展示,不参与筛选资格。保持固定销量版本、账号/仓库/货主/SKU、`business_date<=anchor`、PCS 正出库量及无匹配返回空值。对无销量或大量无效日行的 SKU 仍可能扫描较多行,不能承诺每个 SKU 必定只读取一行。 热销/滞销计数与分页也有类似重复计算,但只有定向测量证实不达标时再扩展,避免把本轮收敛变成全查询重写。 ## 实测后再启用的方案 ### 不完整或过期状态的快速路径 总览已跳过部分无用事实扫描。若“30 日不完整且库存过期”的场景仍耗时,可进一步评估只从固定 profile 身份生成候选数和未知统计,跳过空榜单计算。四种 `complete30 × stockFresh` 组合分别对照,零候选、未发布版本、未知原因优先级和七桶计数均须一致。 该项改善诊断状态响应,不能代替“30 日完整且库存新鲜”的正常经营查询优化,也不优先于总览正常路径。 ### 固定版本结果的有界缓存 如果前述查询调整后仍未达标,再依据测量结果评估进程内有界缓存及同键并发请求合并,不默认新增 Redis 或缓存平台。总览 report 固定计算 30 日,切换趋势范围时存在复用机会;首先评估该稳定数据块,不缓存整页响应。 缓存键必须覆盖账号、仓库、全部实际访问范围、销量与库存版本、范围/修订摘要、固定日期窗、完整性和时效资格、规则版本。容量受条目数及内存预算限制,失败结果不作为正常数据缓存;发布、跨午夜、库存过期、修订屏障及旧版本不可读均须使相关复用失效。 每次请求仍在受控只读快照中完成权限、范围、版本可读性、覆盖和时效校验,重算实时状态。携带固定上下文的请求保留原 `queryAsOf`、业务日期锚点和 `queryExpiresAt`;下钻截止时间依据实际库存时效重算,并受原上下文有效期上限约束,不因缓存命中或翻页续期。一个旧缓存命中不能绕过被删除版本、待重建状态或过期库存的处理;同键请求合并不能把一个请求的上下文直接发给另一请求。 主方案明确要求无业务结果缓存的性能验收,本方案不修改该标准。缓存关闭、首次未命中、同键首次并发和命中分别报告;缓存收益只能作为额外体验改善。若无缓存始终不能达标,总控应提交剩余成本与方案取舍,不能自行以命中数据宣布通过。 本轮不新增固定 30 日 SKU 表、周月表或搜索引擎。若执行计划证明正常请求的全仓 SKU 聚合已是主要且无法继续压缩的成本,再单独评估发布时预计算的读取收益、构建增量成本、跨日期重算和原子发布规则;不能仅为省一次查询把可变结果写回已发布版本。 ## 分开规划采集速度与查询并发 | 链路 | 记录的时间与吞吐 | 与其他链路的边界 | | --- | --- | --- | | 领星目录与逐单详情采集 | 配置间隔、实际请求起始间隔、请求耗时、成功明细数/分钟、429/冷却、剩余目录与详情请求量 | 统一账号级限流及环境独占;不能因有两个仓库就给每仓单独一份额度 | | 本地归并与统计候选构建 | 输入行量、批次量、构建阶段耗时、写入量、发布耗时及磁盘增长 | 使用已落库的事实;统计发布完成与详情下载完成分开记录 | | 页面查询 | 请求并发数、请求组合、实际完成请求数/秒、P50/P95/P99、错误率及各 SQL 耗时 | 读取已发布本地版本,10 个并发用户不等于固定 10 QPS,也不对应领星请求并发 | 总控在 2026-10-13 报告的账号串行小样本中,3/2/1 秒配置档各完成 20 次成功请求,对应平均详情请求间隔约 3.77/2.79/1.86 秒;0.5 秒配置档在约 735 ms 的两次详情请求间隔处出现 429 并停止。这证明配置等待和实际吞吐要分开测量,不能据此推导领星固定配额,也不能由 20 次成功认定可长期稳定维持该速率。总控选择的 1 秒配置不作为本方案的永久安全速率或新默认配额。 这些实测仅用于容量推算与解释来源等待。后续仍遵循[主方案的生产首采与测试请求边界](领星一件代发数据统计一期方案.md#生产首采与测试请求边界)及[接口联调手册](领星WMS接口联调手册.md)的账号预算、冷却和终止规则;本方案不发起新的限流探测,不增加真实采集并发,也不放宽原有请求预算。页面性能验证使用本地合成事实与统计数据。 采集预计完成时间应分为“剩余目录/详情获取、归并、构建、发布”四段。获取阶段根据实际成功吞吐及剩余请求量滚动估算,冷却和失败另计;不能仅用配置间隔乘单数给出整轮完成承诺,也不能因目录页拉完就显示销量已可用。页面分别展示已获取详情、已归并数量、构建阶段、最近完整发布版本及停止原因,沿用既有采集进度合同。 ### 采集速度优化顺序 依据[接口专项的只读反馈](codex://threads/01a12f3f-c57a-79e1-9efa-9401f594544c),本轮复核了当前工作区的获取、路由、等待和预算链路。结论是:**先减少每条详情之后重复执行的本地工作,再减少短间隔等待造成的恢复开销;扩大目录分页作为后续新任务的次要节省项。** 已定位的是源码中的工作量放大,还没有整轮分段耗时证据,不能宣称它已占总耗时的某个比例或承诺若干倍提速。 接口调用单位也要分清:一个出库单详情请求可以带回多个 SKU,当前不是每个 SKU 都发一次详情请求。出库目录由账号共享获取,再分仓处理;产品库存独立按仓全量分页,两条链路不混用过滤能力。 | 顺序 | 已核对的情况 | 候选改进与预期影响 | | --- | --- | --- | | 先保留基线 | 1 秒配置不等于 1 秒实际请求间隔;短样本约 1.86 秒还没有完整分段 | 用现有观测与本地合成回放拆分耗时,不增加领星限流探测;记录生效配置、代码快照及阶段规模 | | 优先 1 | 每拿到一条新详情即执行全量 `route(false)`;按仓逐个检查整批目录 | 保留首次等待任务登记与最终完整路由,中间不再每单重建全量子任务;减少本地查询与子任务写回,不改变必要详情 HTTP 数量 | | 优先 2 | 每次间隔不足可能退出任务、释放租约,随后恢复重新扫描 | 若分段证据确认短间隔让出频繁,评估事务外有界等待或准确的到点调度;减少额外恢复成本,不降低账号最小间隔 | | 随后核对 | 父 manifest 每次整批序列化、重新统计完成量并写回;恢复检查也从开头进行 | 先测累计 JSON 字节、检查点和恢复扫描成本;用可靠的增量计数、变更集合/有界批量减少重复工作,保持可恢复证据。取消全量路由不代表这部分自动消失 | | 后续新窗口 | 官方目录上限 1000,本地出库 Query DTO 与校验上限为 100 | 统一 DTO、适配校验、配置和冻结参数后再验证较大分页;只节省目录请求,不能中途改变已运行任务的分页参数 | | 条件分支 | 批量实际出库明细、可靠修改游标或变更推送尚无已确认合同 | 向供应商核实能力及字段等价性后再设计;这是可能显著减少详情 HTTP 的方向,不能现在直接替换现有来源 | #### 已确认的本地放大点 [SelfopDiscoveryService](../../baiyue-firstleg/lastleg-service/src/main/java/com/baiyue/lastleg/selfoperated/analytics/sync/SelfopDiscoveryService.java) 在详情处理前、每条新详情提交后和全部完成后调用 `route`。其中按配置仓库遍历完整 manifest,对每个对象点查旧订单;相关对象有有效详情时,再读取和解析 stage,并重建子任务 manifest。中途 `detailsResolved=false`,子任务仍等待来源,不会因为这些完整重算提前进入 READY。 设目录对象数为 N、仓库数为 W、本轮实际新增抓取详情数为 K,在不计恢复和修订的基础路径上,旧订单查询方法调用量约为 `W × N × (K + 2)`。代入 N=K=2,787、W=2,约 1,554.6 万次调用。**这是代码循环的条件推算,不是已测 SQL 次数或数据库全表扫描次数**;MyBatis 缓存、事务边界、恢复和分支都会影响实际 SQL 与耗时。首采 K 接近 N 时,这部分工作量近似平方增长。 `saveManifest` 还会序列化父任务整批对象、遍历完成数并更新 task/run;检查点读取包含 manifest 的 task 行,路由又为各仓写回完整 manifest。该成本需要单列。优化不能简单把持久检查点全部改成内存缓存,也不能不落库直到最后;可复用的 VALID stage、对应关联及提交边界必须可靠保留,进程中断不能丢失已取得的详情或错误复用旧版本。 首个最小改动可先减少路由频次,不急于换表或调度平台。最终路由再评估有界批量读取旧归属和有效 stage、每对象解析一次后按仓分组。保留旧仓+新仓联合归属、取消/跨日期修订、`belongsToSlice`、租约栅栏及半归并屏障;全部详情确认前不能让空仓提前发布零量,已经 APPLYING/APPLIED/BLOCKED 的子任务不能被覆盖。页面等待关联和进度继续使用轻量投影,不靠重复全量路由维持可见性。 #### 额外等待不等于供应商请求时间 [SelfopEgressService](../../baiyue-firstleg/lastleg-service/src/main/java/com/baiyue/lastleg/selfoperated/analytics/request/SelfopEgressService.java) 的 `ACCOUNT_INTERVAL_WAIT` 在发出领星 HTTP 前产生;[SelfopExecutionService](../../baiyue-firstleg/lastleg-service/src/main/java/com/baiyue/lastleg/selfoperated/analytics/sync/SelfopExecutionService.java) 将执行让出并释放租约。调度器 `fixedDelay=1000` 表示当前 tick 的同步任务处理结束后再等 1 秒,不是保证每秒准时启动。出库任务恢复还包含重新获取租约、建立尝试和读取/扫描 manifest。 [LingxingEgressGate](../../baiyue-firstleg/integration-service/src/main/java/com/baiyue/integration/provider/lingxing/LingxingEgressGate.java) 在实际 HTTP 开始前另有账号保护,只等待尚未满足的剩余间隔。HTTP、落库和路由也消耗时间,不能把两处配置间隔简单相加。Lastleg 的持久 `minIntervalMs` 采用旧值与配置值的较大者,配置改成 1000 也不能直接证明实际已按 1000 生效;应只读核对实际许可和 HTTP 时间,不为本次梳理清空保护状态。 短间隔优化仅针对可恢复的普通间隔等待:事务外有界等待后重新校验租约、截止时间、账号保护及预约资格。等待超界、限流冷却、会话预算耗尽和结果不确定仍走原有让出/暂停路径;不能持有数据库事务或行锁睡眠,不能无限占用唯一调度线程,不能为了减少尝试数跳过重新授权。是否使用短等待还是到点调度,由实测等待分布和调度公平性决定。 | 事件 | 领星真实 HTTP 与预算 | | --- | --- | | 预约前因最小间隔/冷却/在途被拒绝 | 不发领星 HTTP、不增加持久 HTTP 预留;此前本轮内存工作额度可能已消耗,需与请求预算分开统计 | | 成功预留后、发送前失败 | 可能没有真实 HTTP,但预留与根会话额度不自动退还;不能据 reserved 数认定已调用领星 | | 已开始的超时、429 或业务失败 | 消耗一次真实请求;有回执时按实际调用数确认,未知结果保持保守预留 | | 重试/重新定位/再取详情 | 每次均重新授权计额;当前 Integration 没有隐藏的供应商 HTTP 重试循环 | 内部 reserve/authorize/complete 通信也有成本,但不是领星请求。下一轮性能证据分别记录内部调用数、真实 HTTP 数、预留额度和确认额度,不用 run 次数或重试次数代替外部调用次数。 #### 哪些请求可以减少,哪些还不能省 官方[出库分页](https://apidoc-omp.xlwms.com/reference/post_openapi-v2-order-delivery-page-1.md)目前公开的请求字段没有仓库过滤,最大页大小为 1000;返回仓库编码不代表请求支持按仓筛选。按两个仓库重复扫同一账号目录不节省请求,当前账号共享采集设计应保留。 以 2,787 单、两个稳定目录扫描轮次、所有订单均需一次详情、无异常重试为例:每页 100 需要 56 次目录请求,每页 1000 需要 6 次;加上 2,787 次详情,总量约从 2,843 降到 2,793,少 50 次,约 1.8%。这里只是基础请求量推算,不含重新定位、修订、库存等;真实收益还受响应大小和分页稳定性影响。已经完成目录的当前任务,不会因扩大未来分页而加快剩余详情。 列表虽然有 `productList[].qty`,官方未明确它在部分出库、差异出库及后续修订中等同实际出库量;[详情](https://apidoc-omp.xlwms.com/reference/post_openapi-v2-order-delivery-detail-1.md)明确区分 `deliveryQty` 与 `actualDeliveryQty`。当前统计需要后者,不能仅因列表包含 SKU 和数量就删掉详情请求。列表的批量单号筛选也不等于批量实际明细。 已有有效详情且没有更新观测时,当前代码会跳过 HTTP;这项应保留,不再作为从零开发的优化。新的观测代次、身份失配或修订要求重新核实时,仍需读取或重新定位。当前公开时间筛选未确认可靠的修改时间游标,不能永久以“列表字段没变”判断详情无需复查,也不能删除第二轮目录稳定性核验来制造提速。 需要供应商确认的高价值问题是:已出库列表 qty 的完整语义、批量实际明细能力、带稳定游标的修改时间增量/变更推送、历史修订与取消范围,以及账号级/接口级速率、突发和在途限制。当前未找到已确认能力不等于供应商没有这些能力;取得契约与针对性对账证据后,才能评估替换详情链路的收益。本轮不联系供应商、不增加试探调用。 #### 最小测量与验收 先复用已有日志和只读统计。缺少的分段埋点留给后续开发工作包,不为测量新增真实采集、加大并发或反复重跑已完成日期。每轮证据关联同一任务、尝试和出站许可,保留代码版本、N/W/K、复用比例、生效间隔、已发布覆盖、同机负载及预算边界。 | 测量组 | 必须区分的指标 | | --- | --- | | 外部调用 | 各接口 HTTP 数、实际起始间隔、HTTP 耗时、成功新增详情/分钟、429/超时;复用完成量不算新增下载速度 | | 调度与保护 | 最小间隔拒绝数、可再次尝试时刻、到点至实际恢复的延迟、租约获取/begin 耗时、内部授权/完成回执耗时 | | 本地处理 | 详情检查点、route、最终路由、归并/构建/发布分别计时;订单/stage 方法调用与实际 SQL 次数分别记录 | | 序列化与恢复 | manifest 大小、累计编码/解码字节、子任务写回次数、恢复重扫对象数、峰值内存和数据库连接等待 | 实际 HTTP 起始间隔、详情提交间隔和整阶段耗时分别报告;用同一请求链中不重叠的时间段解释墙钟耗时,不将互相覆盖的保护等待重复相加。先回答本地重复工作、外部等待各占多少,再决定线程数、连接池或并发调整;短样本不能证明长期限额。 离线对照建议固定 N=100/1,000/3,000、W=1/2,使用假领星 Client 和计数 Mapper,比较优化前后的必要 HTTP 数、route 次数、查询调用、JSON 字节、子任务写回和最终结果。覆盖部分恢复、全部复用、新观测强制复查、跨仓、取消、时间切片、零单、提交回滚、租约失效、等待超界及冷却。证明减少工作量且结果/恢复语义等价后,再按总控有效授权验证实际数据库耗时与整阶段吞吐;离线替身耗时不能冒充数据库提速。 本轮不承诺减少必需详情数量,不修改正在运行任务的分页、租约和会话预算,不为赶速度增加账号并发。采集页改版仍按已确认设计推进;这些采集性能候选由总控另行安排,不能把未经测量的优化变成当前页面交付的前置条件。 ## 真实数据覆盖与容量样本用途 此前几分钟的真实销量样本只能验证局部链路。总控为功能验证补采的两仓单日 2,014 单,也必须完成目录核对、详情获取、归并与覆盖/发布校验后,才能用于判断对应日期的结果;目录数量相同或 HTTP 全部成功本身不证明业务日完整。 一个日期的数据完整不代表最近 30 日完整,也不自动补足每个 SKU 的观察期。相应平均销量、可售天数、无销量结论及榜单资格仍按主方案判定;不能为让页面出现数字把未覆盖日补零。真实功能样本与合成容量数据分别标注账号范围、仓库、统计版本、覆盖区间、观察依据及库存新鲜度。 功能核验可先使用真实单日结果,并用已有合成数据检查完整 30 日榜单、边界和下钻。容量验收必须包含“30 日完整且库存新鲜”的正常经营路径;观察不足或库存过期导致跳过聚合的快速响应仅代表该状态,不用于替代正常路径性能结果。 ## 正确性与性能验收 所有 SQL 调整保留当前 API、权限、六位小数数量口径、统计版本、北京时间业务日及未知值规则。不会因为优化改变页面字段、图表范围、榜单资格或库存新鲜度。 | 对照组 | 必须验证的结果 | | --- | --- | | 两仓、同 SKU 不同货主、仅单版存在的 SKU | 身份不串仓/不串货主,候选并集不丢失;名称优先级不变 | | 完整/部分/未知销量、真实零量、单位冲突 | 正式量、已采集量、未知数量及原因一致,未知不能变成零 | | 新鲜/过期库存与完整/不足 30 日的四种组合 | KPI、榜单、七桶和下钻资格一致;正常完整场景单独计时 | | 边界 30/60/90 天、零可售、次品/冻结、短观察期 | 分桶用原精度比较;有限天数、无销量和未知不混算,库存品质不放大销量 | | 首末页、越界页、空结果及并列销量/天数 | total、顺序及业务键一致;不先取 Top 10 再算全仓分布 | | 发布切换、旧版、修订屏障、跨午夜、库存到期 | 同请求读一致快照;严格下钻拒绝规则及独立销量读取不变 | | 小数与最后出库日 | 小数汇总不提前取整;最近日期条件不放宽,无匹配仍为空 | 响应对照使用同一逻辑时钟与固定输入,逐字段比较;真实 HTTP 中必须变化的请求时间/诊断标识单独核对,不以整段忽略 context 的方式让对照通过。 每项候选先完成直接回归和 SQL 对照,再串行复测同档 HTTP,记录 P50/P95/P99、样本数、错误数、每请求 SQL 数、数据库耗时、扫描及临时结果、响应大小。相同资源下重复比较以排除波动;不能靠提高超时、减少候选、缩短统计范围或跳过资格校验获得收益。 最终验收沿用主方案:单仓 1 万货主+SKU、单销量版最多 366 万条稀疏日行、当前及至少两个旧版,并验证两仓隔离。无业务结果缓存,10 并发稳定至少 5 分钟;各类用例需要分别有足够样本,低于 100 个成功样本的路径只作抽测,不用其 P95 宣布通过。缺失阶段或失败请求不能从汇总中静默排除。 | 性能场景 | P95 目标及边界 | | --- | --- | | 经营总览 | ≤1.5 秒 | | 五种常用范围的 SKU 清单、7/30 日榜单、库存各关注筛选/排序、货主概览 | ≤1 秒 | | 366 天自定义 SKU 清单 | ≤2 秒,覆盖当前及仍可读旧版 | | 单 SKU 日趋势、货主选项、采集运行元数据查询 | ≤500 ms | | 全部正常合法请求 | 无超时/错误;首次与预热、单用户与并发、深分页分别报告 | 同档后台候选构建期间也要满足查询目标,并验证只读完整旧版;构建耗时、扫描、写入及磁盘增长单独报告。增加原单和旧统计版本后,当前固定版本查询不能扩大成原单/全部版本扫描。查询不访问 order/item/stage,不调用领星;合成容量验证不能通过开启真实采集获得数据。 ### 并发与后台构建的对照矩阵 | 场景 | 固定条件与增加的负载 | 应取得的证据 | | --- | --- | --- | | 查询单独运行 | 单用户与 10 并发分别记录;请求组合、分页深度、日期范围、双版本、资格状态及资源不变 | 每条路径分别统计样本量和时延;默认库存作为已达标回归项,总览与销量作为主要改善对象 | | 查询与候选构建重叠 | 相同查询读取原固定版本,同时启动规模明确的本地候选构建 | 记录真正重叠的起止时间、构建阶段、输入/输出行量、批次及进度,关联查询时延、连接等待、CPU/磁盘;不能仅以后台曾启动证明已覆盖竞争 | | 查询与采集落库重叠 | 如需验证,采用受控合成输入,并单列写入速率与持续时间 | 与前两组分别比较,保留归并/写入的干扰证据;不调用领星制造压力 | | 版本发布边界 | 新旧版切换前后的请求分别标记,固定上下文仍读取原版 | 版本一致、无半份数据、到期拒绝正确;不把发布后更换数据范围的请求混入同一 A/B 结果 | 请求组合先覆盖既有近 15 日总览、销量和默认库存,再增加常用范围、长窗口、复杂筛选及深分页;记录每类占比,不能改变组合后直接比较整体平均值。主读阶段仍要求稳定至少 5 分钟;短构建或短采样仅标明覆盖到的阶段,其余阶段保留未验证。是否单独追加容量档位由实际使用需求决定,不自行把 10 并发目标扩展为新的大规模压测要求。 ## 交给开发总控的工作包 以下工作包在功能与人工页面验收安排后启动;当前仅更新规划和证据,不向总控追加立即执行的性能任务。 | 顺序 | 工作包 | 完成条件 | | --- | --- | --- | | 1 | 复用完整基线与诊断 | 复用 1,991 次请求的完整基线及 39 次分段诊断,核对功能修复后的可比性;仅补缺失或已变化的证据 | | 2 | 对准总览 report 与销量 page | 现有采样已明确主要 SQL 成本;补查计划及资源竞争中的剩余问题,默认库存保持回归,不重做无收益实验 | | 3 | 验证有证据的新候选 | 用具体减少的扫描/聚合/排序工作量说明收益来源;复杂筛选共享聚合按其自身瓶颈选题,窄投影、profile 归并和延后名称无新证据不重做 | | 4 | 全场景验收 | 按主方案完成无缓存、长窗口/旧版、下钻及上述混合负载矩阵;无稳定收益候选不进入最终实现 | | 条件分支 | 退化状态快路/固定版有界缓存/发布时预计算评估 | 仅在前述证据支持时展开,不自动增加本轮表结构或平台依赖 | 总控指定查询实现的唯一写入者;只读评审、回归设计可以内部并行,Maven、部署和共享环境压测窗口继续串行协调。现有查询、Mapper、SQL 基线由其当前写入者维护,本次文档交接不另行移交文件写权,不创建独立对话。 每个候选交付“修改点与版本、固定输入、响应对照、前后执行计划、同档性能结果、是否保留及理由”。已试验未显示稳定收益的方案保留结论,新派工先查重;有实质差异才重新验证。测量完整后再决定下一项,不以预计收益百分比代替结果。本文不授权部署、SQL 执行、环境写入或真实领星调用;这些操作继续沿总控已有有效授权和工程约束安排。