首页 新闻 会员 周边

利用SqlBulkCopy做数据交换遇到的棘手内存消耗问题!

0
悬赏园豆:100 [待解决问题]

本地多个任务要执行库中的某些表批量导入到其他服务器的相关表,每个表表记录数为百万级,由于交换速度有要求,目前采用的是ADO.NET SqlBulkCopy结合Quartz.NET调度实现定时作业的。 但遇到的问题是我单个任务执行1张表的完全导入300万条记录,目标服务器的内存已接近98%,而且这个内存不会降低,除非手动重启mssqlserver。但重启mssqlserver是不太可能的。后期多任务执行多表,怎么避免内存超高不降低的问题?

BruceGoGo的主页 BruceGoGo | 初学一级 | 园豆:34
提问于:2016-11-30 16:29
< >
分享
所有回答(5)
0

数据库肯定认为100%的内存都是自己能用的.什么时候该释放内存也是数据库自己的事情.

你可以设置数据库的可用内存最大值.他就只用那么多内存了.

吴瑞祥 | 园豆:29449 (高人七级) | 2016-11-30 16:41

但还是比较担忧,后期几百个job一起上之后,每个job数据量很大,数据同步频率有高有低。担心sqlserver查询性能也有很大的影响。

支持(0) 反对(0) BruceGoGo | 园豆:34 (初学一级) | 2016-11-30 16:44

@BruceGoGo: 什么时候该释放内存.sqlserver比你懂.这个能理解不..

担心内存占用过多对性能产生影响,你该做的是加内存.

支持(0) 反对(0) 吴瑞祥 | 园豆:29449 (高人七级) | 2016-11-30 16:48
0

sqlserver吃内存正常啊,如果系统觉得内存不够,sqlserver会释放出来的。

你这里主要看服务器io,cpu是否在安全范围内就可以了。

规避你的问题我觉得你可以考虑以下几个方案

1.换内存数据库(之前使用mongodb做过类似的玩意,数据数量级在2-3亿,单进程写入在43k/s,db上没太大压力)

2.定时任务跑起来是否能平滑些,比如你1hr做一次能否变成1hr做10次?

 

 

Daniel Cai | 园豆:10424 (专家六级) | 2016-11-30 16:44
0

其实SQL会自动占用一系列的内存用来工作时使用, 你设置数据库最大内存就行了。

不过这样转换, 何时是一个头呀。 

如果其它的系统要用到这些数据,  为什么不在这个数据服务器外配上一个web service服务器, 让相应的人来请求返回数据。 这样不停的复制数据到A 明天又加到B,后天又加到C, 会越来越乱。 

创建一个web service的可扩展性又高,要什么样的数据, 添加不同的web service接口, 例如:

现在可以设置三组服务器, 一组用来前端主力正常使用, 一组用来订阅, 这组服务器外边配一个web service服务器, 再配一组来做备份。 

 

风浪 | 园豆:2996 (老鸟四级) | 2016-11-30 16:51

数据交换本身至少需支持DB、WebService、文件共享类这几种,WebService、文件共享都不是问题。现在遇到的问题是处在DB上。另外,客户目前的需求是只能提供前置机服务器用来做数据交换。

支持(0) 反对(0) BruceGoGo | 园豆:34 (初学一级) | 2016-11-30 17:09

@BruceGoGo: 那设定SQL服务器占用的内存空间吧

服务器右击, 属性, 最大内存

 

我测试了, 5000万条数据, 设置内存为1024M最大, 他涨到1024左右, 就不再涨了。

开始时占用的数据

结束后占用的数据

支持(0) 反对(0) 风浪 | 园豆:2996 (老鸟四级) | 2016-12-01 11:09

@风浪: 谢谢亲自撸代码的仁兄,点个赞!这个我也按你说的修改db内存阀值得,但内存设置阀值上限后后,对查询速度影响很大。一直在找降低内存的方法,可没找到,可能这个SqlBulkCopy本身就不支持自动释放。

支持(0) 反对(0) BruceGoGo | 园豆:34 (初学一级) | 2016-12-01 15:24

@BruceGoGo: 是的, 占用大内存, 主要是SQL Server申请了, 你不能手工释放。 考虑一下发布订阅, alwayon这些吧, 这些功能总比这样手工同步数据好

支持(0) 反对(0) 风浪 | 园豆:2996 (老鸟四级) | 2016-12-01 17:04
0

数据库将内存充分利用了,是好事。不过300万数据一次导,未免有点太多了,建议分批进行



我叫So | 园豆:186 (初学一级) | 2016-11-30 21:24

一次一万,循环300次。

支持(0) 反对(0) BruceGoGo | 园豆:34 (初学一级) | 2016-11-30 21:27

@BruceGoGo 不知道你的表字段和大小如何,一次导多少最好是根据你们的实际情况决定。


支持(0) 反对(0) 我叫So | 园豆:186 (初学一级) | 2016-11-30 21:33
0

这个问题感觉好像是,你看我有十万,要做一个微信,还得比微信好,打败微信。

我一年有一百多万个软件要开发,公司就一个人,怎么避免这人太忙。

 

说句实话,你又不上代码,谁也不知道你写得咋样,只能假设你写的已经是天才级的,

无可优化了。

那么怎么办,

1、升级硬件,

2、多种不同写入方法测试并做日志记录。

3、当然,愿意重新审视一下自己代码中可以优化的也是一个可行的方法。

爱编程的大叔 | 园豆:30839 (高人七级) | 2016-11-30 21:40

你可以模拟试试300w的行数据,每行50个字段,做300次循环调用SqlBulkCopy操作,每次循环按1w条记录来操作,设置SqlBulkCopy的BatachSize=1000,看执行完后,被插入的数据库的内存是不是像我描述的那样内存增高持续不降。若有好的办法释放内存,可以让每次循环后的内存保持浮动不上涨太大就真的非常感谢你了!

支持(0) 反对(0) BruceGoGo | 园豆:34 (初学一级) | 2016-11-30 23:01

@BruceGoGo: 你看来真是没仔细看我的回复了。

1、你的问题描述是不够清楚的,或者说是自相矛盾的。

你需要内存占用小,还需要快。(注意,这两个需求是矛盾的)

2、你这事情每天运行几万次?你可以添加内存么?你可以升级CPU么?你可以升级硬盘么?

3、我说了,假设你的代码写得已经是年薪千万级的。

测试是你需要做的事情,你想要内存占用低,慢点就行了。

要不然就是让服务器快点。

要不然就是你把代码,环境全部贴出来,才有可能有人找出你几千万年薪代码的

也许不小心出现的小问题,

支持(0) 反对(0) 爱编程的大叔 | 园豆:30839 (高人七级) | 2016-12-01 10:58

@爱编程的大叔: 谢谢指点。

支持(0) 反对(0) BruceGoGo | 园豆:34 (初学一级) | 2016-12-01 11:12
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册