批量数据导入的性能与完整性问题

刚才有网友问了一个技术问题:

我从其他接口 采集一批数据,每次上万条左右,然后存到数据库,存库前还要每条每条的判断数据库存不存在这条数据,不存在才能写库,有没有性能好的实现思路啊?

这是典型的批量数据导入的问题,一般追求是速度。

8年前来澳洲后第一份工作是一个做智能表(水电煤等)的公司,软硬件结合,软件系统采集数十万的智能表的数据,系统里一些表,单个超过30亿条记录,每天更新上千万条记录,为了这个专门实现了一个高度优化的批量导入功能。

现在拿微软SQL Server做例子,说说思路。

首先,要实现速度,会考虑批量导入(Bulk Copy),但一般来源数据格式和目标表达格式不一样(譬如字段数量、类型等),甚至需要做一些计算,甚至要从关联表取数据,所以一般先会导入到临时表,然后再插入目标表。

使用Bulk Copy有一个问题,是它不确保插入数据的顺序,所以如果你必须要求数据插入完全按照来源数据的要求,你必须确保Bulk Copy之前主键字段的值是按顺序的,因为簇集索引是物理顺序,所以会默认按这个排序。

插入目标表需要考虑2个问题:

  1. 唯一性:主键可能会重复,一般采用修改主键索引忽略重复记录,但是这个做法可能会忽略掉后面比较新的数据。
  2. 完整性:如果这个批量导入逻辑可以是多线程/多进程跑的话,那么需要额外的逻辑去处理不会重复操作。

插入数据要确保唯一性又要考虑最新数据会被导入,一般做法是判断目标表是否存在数据,如果不存在则插入,如果存在则更新,这个操作是有重复处理浪费时间,所以可以用SQL Server的MERGE语句,把插入和更新合二为一。

有朋友问:“那是否有更快的办法?”。是有的,那就是支持多线程/多进程。思路如下:

  1. 客户端调用BulkCopy,获得起始、结束Id
  2. 完成调用服务器的存储过程处理这批数据

这样做可以支持并发问题,提高性能。

如何成为爆栈成员:

  • 加我微信 unruledboy ,进入技术群

版权所有

所有文章内容版权所有,任何形式的转发/使用都必须先征得本站书面同意。本站保留一切追究的权利。

灵感之源的爆栈服务

我是 爆栈 的作者,我全面掌握:系统开发技术栈、Web前端开发技术栈、数据库技术栈、.NET技术栈!

不是我针对你,我想说,在座,很多都在写垃圾代码甚至不懂开发!

是否想技术水平快速提升?是否希望快速成为公司的技术骨干?

本人拥有有15年的大型分布式系统开发、架构、设计和管理经验,写过1000万下载量的免费软件,03年开始参与开源项目,#爆栈#系列作者。最近8年专注研究新技术研发,给不同的团队引入前沿技术,包括云、大数据、混合现实等。曾任多个公司的技术带头人、研发经理和全球领先的上市物流系统公司的高级架构师

从事过的行业:包括不仅限于互联网、移动和大数据库,曾在网络支付、物流、医疗、能源、移动设备管理等领域深耕多年

核心价值

  • 把我这10多年来所学到的知识、总结的经验、吸取的教训分享出来
  • 发布每周我看过的新文章、学到的新东西
  • 针对不同的学生量身定制规划学习成长路线、1对1个人指导(私聊)
  • 解答各种技术问题(会员群)
  • 为公司提供技术解决方案(增值服务,按时间收费)
  • 提供基本的技术移民澳洲咨询
擅长领域:
  • 数据存储(SQL Server、PostgreSQL、Redis、Couchbase、MongoDB、SQLite等)
  • Cloud云开发(Azure)
  • 大数据处理(Kafka、Spark、Scala、Elasticsearch、Kibana等)
  • .NET (C#、CLR、ASP.NET MVC、.NET Core、ASP.NET Core等)
  • 系统设计与开发
  • Web前端(Angular JS)
  • 澳洲技术移民

服务时间:

  • 工作日:北京时间早上10点到晚上10点,白天时间大部分时间不在线,晚上大部分时间在线
  • 周末:早上10点到晚上10点,大部分时间在线
  • 关于技术解答,如果本人无法在短时间内解决的,会明确告诉你并且附带上可能的解决办法(相关资源)

如何成为会员:

  • 加我微信 unruledboy ,进入会员群,获得相关服务

版权所有

所有文章内容版权所有,任何形式的转发/使用都必须先征得本站书面同意。本站保留一切追究的权利。