4. 分区策略选型对比

逐笔行情数据有两个鲜明特征:一是写入量极大且持续不断,二是查询几乎总是围绕“某只证券、某段时间”展开。分区策略的选择,本质上是在回答一个问题——把一张巨大的逐笔表切成若干物理片段时,切分键应该选谁、按什么规则切。选错了,写入会集中到少数分区形成热点,或者查询要扫描全部分区;选对了,写入能均匀摊开,查询能精准裁剪。本节围绕范围分区、列表分区、哈希分区与组合分区四种策略,结合逐笔行情的数据分布与访问模式给出选型依据。

四种策略的切分逻辑与逐笔场景映射

范围分区按分区键的连续区间切分,典型做法是以交易日期或时间戳为键,每天一个分区,或每小时一个分区。它的最大优势是时间维度的裁剪极其干净:查询“2024-06-03 09:30 至 10:00 的逐笔成交”时,优化器只需命中当天分区,甚至能进一步定位到小时分区,其余分区完全不参与扫描。同时,按时间滚动的新增分区天然对应“新数据只写最新分区”,历史分区只读,便于做冷热分离和归档。缺点是如果分区键选择不当,比如按证券代码范围切分,写入会随热门股票的成交活跃度倾斜,形成写热点。

列表分区按分区键的离散枚举值切分,例如按交易所(上交所、深交所、北交所)或按证券板块(主板、创业板、科创板)划分。它适合取值集合有限且业务上经常按该维度过滤的场景。在逐笔行情中,如果下游大量查询是“只看某个交易所的全部逐笔”,列表分区能让这类查询只命中一个分区。但列表分区的粒度受限于枚举值数量,交易所只有几个,无法解决单分区数据量过大的问题;而且新增枚举值(如新增一个交易板块)需要显式维护分区定义,运维上不如范围分区自动。

哈希分区对分区键做哈希取模,把数据均匀打散到固定数量的分区中。它最擅长消除写热点:以证券代码的哈希值为键,热门股票和冷门股票会被分散到不同分区,单分区写入压力被摊平。代价是查询裁剪能力弱——按证券代码点查能定位到唯一分区,但按时间范围查询时,由于同一时间段的数据散落在所有分区,必须扫描全部分区。因此哈希分区更适合“按证券代码点查为主、时间范围查询为辅”的访问模式,或者作为组合分区中的二级切分手段。

组合分区是前两者的叠加,常见形式是“范围 + 哈希”或“范围 + 列表”。逐笔行情最典型的组合是:一级按交易日期做范围分区,二级在每个日期分区内按证券代码做哈希子分区。这样时间范围查询能裁剪到少数日期分区,日期分区内部再按证券代码哈希打散,既保留了时间裁剪,又缓解了单日热门股票集中写入的问题。组合分区的代价是分区总数膨胀(日期数 × 哈希桶数),元数据管理和分区裁剪的复杂度上升,需要控制层级深度,一般两级足够。

逐笔行情分区策略:切分逻辑与访问模式匹配 范围分区 键:交易日期 / 时间戳 06-01 分区 06-02 分区 06-03 分区(写入) ✓ 时间裁剪强 ✗ 单日热点难分散 列表分区 键:交易所 / 板块枚举 上交所分区 深交所分区 北交所分区 ✓ 交易所过滤精准 ✗ 粒度粗、枚举需维护 哈希分区 键:证券代码哈希取模 桶 0(代码散列) 桶 1(代码散列) 桶 2 … 桶 N ✓ 写入均匀、无热点 ✗ 时间范围查询全扫 组合分区 一级日期范围 + 二级代码哈希 06-03 分区 子桶 0 子桶 1 子桶 2 子桶 3 ✓ 时间裁剪 + 写入打散 ✗ 分区数膨胀、管理复杂 访问模式 → 策略匹配 按时间范围回放/统计 → 范围分区 按交易所/板块过滤 → 列表分区 按证券代码点查 → 哈希分区 时间范围 + 代码点查混合 → 组合分区 逐笔行情选型判断依据 ① 写入是否集中:单日热门股票成交占比高 → 需哈希打散 ② 查询是否带时间窗:带时间窗 → 必须保留范围分区做裁剪 ③ 分区总数是否可控:组合分区层级 ≤ 2,避免元数据与裁剪开销失控

结合数据分布与访问模式的选型依据

先看数据分布。逐笔行情在时间维度上分布相对均匀——每个交易日的数据量大致相当,开盘和收盘时段略高但不会出现数量级差异;而在证券维度上分布极不均匀,头部几十只活跃股票的逐笔条数可能占到全市场的相当比例。这意味着:以时间为键切分,各分区大小可控;以证券代码为键切分,若不做哈希而直接按代码范围切,必然出现热点。因此时间维度适合做一级切分,证券维度适合做哈希打散,而不是范围切分。

再看访问模式。逐笔行情的下游消费大致分三类:一是回放与因子计算,按时间窗口顺序读取某段时间的全部逐笔;二是单票分析,按证券代码拉取某只股票的历史逐笔;三是实时监控,持续写入最新数据并做窗口聚合。第一类要求时间裁剪,第二类要求代码定位,第三类要求写入均匀。单一策略很难同时满足三者,这正是组合分区在逐笔场景中往往成为默认答案的原因。

给出一个可参考的示例配置(参数为教学假设,非实测):一级按交易日做范围分区,保留最近 90 个交易日在线,更早的分区归档;二级在每个日分区内按证券代码哈希分成 16 个子分区。假设单日逐笔约 2 亿条、单条约 120 字节,则单日数据约 24 GB,单个子分区约 1.5 GB,处于多数数据库单分区较舒适的区间。查询“某日 09:30–10:00 全部逐笔”时,裁剪到 1 个日分区、扫描其下 16 个子分区;查询“某只股票近 5 日逐笔”时,裁剪到 5 个日分区,每个日分区内只命中 1 个子分区。写入侧,当日新数据分散到 16 个子分区,热门股票不会压垮单一分区。

策略 切分键示例 写入均匀性 时间范围裁剪 代码点查定位 适用判断
范围分区 交易日期 中(单日热点集中) 强 弱(需扫全分区) 以时间回放为主、写入压力可控
列表分区 交易所 / 板块 中 弱 弱 按交易所强过滤、数据量不大
哈希分区 证券代码哈希 强 弱(全分区扫描) 强 单票点查为主、写入热点突出
组合分区 日期范围 + 代码哈希 强 强 强 混合访问模式、数据量大

落地时的几个关键取舍

第一,分区粒度要按“单分区数据量”反推,而不是拍脑袋定天数。若单日数据量已经很大,可把一级范围分区细化到小时;若单日数据量适中,按日分区即可,过细会导致分区数量暴涨、元数据开销和查询规划时间上升。第二,哈希桶数应取 2 的幂或便于取模的整数,并在容量增长时预留扩展方案——固定桶数在数据量翻倍后单桶会变大,需要提前规划重建或改用一致性哈希。第三,组合分区不要超过两级,三级以上带来的裁剪收益递减,而管理复杂度和跨分区查询成本明显上升。第四,无论选哪种策略,都要用真实查询语句验证分区裁剪是否生效,例如查看执行计划中扫描的分区列表,确认时间条件确实把无关分区排除掉了,而不是停留在“建了分区就应该快”的假设上。

选型口诀可以概括为:时间窗查询多、写入压力可控,优先范围分区;单票点查多、热点明显,考虑哈希分区;两类查询都重且数据量大,用“日期范围 + 代码哈希”的组合分区;列表分区更适合作为交易所、板块这类低基数维度的辅助切分,而非逐笔表的主切分手段。