大量结构化测量数据存为BLOB是否合理?MSSQL业务场景技术问询
方案可行性判断
你的方案完全具备可行性,且「操作单个大型BLOB远快于操作百万条独立记录」的判断100%正确:
- 插入、删除操作从处理百万行记录、维护
series_id索引的重IO操作,变成了单条记录的增删,耗时会从几十秒降低到毫秒级,完全解决锁表、写入超时、删除超时的问题 - 原来占磁盘空间超过表本身的
series_id索引可以完全简化为单条记录的普通索引,索引开销几乎可以忽略,整体数据库容量会大幅下降 - 预存抽稀后的数据集后,99%的查询场景直接返回
reduced_data即可,无需实时抽稀计算,查询耗时会从10秒级降低到毫秒级,同时彻底避免重复抽稀的CPU开销
BLOB存储格式选择
你认为「gzip压缩的CSV/JSON比自研二进制格式更划算」的判断完全正确:
- 自研二进制格式需要额外开发序列化、反序列化逻辑,还要处理后续的格式迭代兼容、问题排查等维护成本,收益只有很小的体积优化,投入产出比极低
- gzip压缩的JSON/CSV有成熟的类库支持,C#和前端都可以直接处理,几乎没有额外开发成本
- 如果存储预压缩的JSON内容,查询时可以直接设置
Content-Encoding: gzip响应头,把BLOB内容直接返回给前端,无需服务端额外解压再压缩,进一步节省CPU开销 - 若后续有用户需要导出全量原始数据的需求,CSV/JSON格式的通用性远高于自定义二进制,无需额外转换即可直接交付给用户使用
你可能忽略的BLOB存储潜在问题
- 大对象堆碎片化问题:处理BLOB读写时尽量使用流式操作,C#中推荐用
SqlBytes类型读写varbinary(MAX)字段,避免把整个BLOB一次性加载到内存中,减少大对象堆(LOH)碎片化,降低IIS进程的内存开销 - 存储布局优化:建议将
Values表的BLOB字段单独存放在独立的文件组中,和Series表、索引等小数据的存储分开,提升IO性能 - 抽稀数据版本兼容:如果后续抽稀规则有调整,建议在
Values表中新增reduced_version字段标注抽稀版本,避免旧规则生成的抽稀数据无法识别需要重新生成 - 冗余字段预留:如果后续有按X/Y范围过滤序列的需求,可以直接在
Series表中冗余存储整个序列的x_min、x_max、y_min、y_max等极值字段,无需解析BLOB即可完成过滤,不影响查询性能
补充建议
如果你的单条原始数据BLOB普遍大于100MB,且有高频的全量原始数据读取需求,可以考虑开启MSSQL的FILESTREAM特性,直接通过文件系统接口读写BLOB,IO性能会更高,否则直接用varbinary(MAX)即可满足需求。
内容的提问来源于stack exchange,提问作者Jens
相关产品推荐
相关产品推荐

