大数据量的读写问题

时间:2023-01-11 23:43:51
业务逻辑是这样的:

1.从数据中的Table1中读取数据到应用程序,对nvarchar字段做一些处理,Table1有4千万条记录,每次读入应用程序大概读取1万条,对这1万条记录处理后,在应用程序中得到4~5倍的记录,也就是4~5万条;

2.将应用程序中处理后的记录写回数据库的Table2,需要将应用程序中的nvarchar字段写入Table2,但是在写之前需要做判断,如果Table2中有这条记录,就不写入;另外还需要将该nvarchar对应的一个uniqueidentifier字段一并写入Table2,nvarchar与uniqueidentifier组成一条完整的记录。 关键是uniqueidentifier来自Table3,但是对Table3做一次查询,需要6~7分钟(Table3表很大)。

因为 写入数据库之前需要判断是否有重复的记录,所以我现在的策略是 对应用程序中的数据逐条判断,因此在Table3中取uniqueidentifier也是逐条读取的,所以造成时间开销很大,我的数据源有4千万记录,这样做的话从理论上说是根本没法完成的。

现在请教各位,有什么好的策略来完成这样一项工作呢。

14 个解决方案

#1


可否放在服务端处理数据,数据的判断可否不一条一条处理

#2


引用楼主 sinxy 的帖子:
业务逻辑是这样的: 

1.从数据中的Table1中读取数据到应用程序,对nvarchar字段做一些处理,Table1有4千万条记录,每次读入应用程序大概读取1万条,对这1万条记录处理后,在应用程序中得到4~5倍的记录,也就是4~5万条; 

2.将应用程序中处理后的记录写回数据库的Table2,需要将应用程序中的nvarchar字段写入Table2,但是在写之前需要做判断,如果Table2中有这条记录,就不写入;另外还需要将该nvarchar对应的一个unique…


我个人建议,用某种开发语言自己提取相关数据,然后用循环逐一判断,然后写入表中.

这么大的数据量,估计直接用SQL写会造成内存等的崩溃.

#3


数据逐条判断的时候不要用foreach,要用for比较快效率应该会提高些

#4


引用 2 楼 dawugui 的回复:
引用楼主 sinxy 的帖子:
业务逻辑是这样的:  

1.从数据中的Table1中读取数据到应用程序,对nvarchar字段做一些处理,Table1有4千万条记录,每次读入应用程序大概读取1万条,对这1万条记录处理后,在应用程序中得到4~5倍的记录,也就是4~5万条;  

2.将应用程序中处理后的记录写回数据库的Table2,需要将应用程序中的nvarchar字段写入Table2,但是在写之前需要做判断,如果Table2中有这条记录,就不写入;另外还需要将…

他现在的问题是数据量太大,而又必须要去处理它,所以对其他的环节基本没有什么好的方法,听他的描述我觉得瓶颈应该在对TABLE3的相关处理上,鉴于你对TABLE3做的多是查询工作,比较少的插入和修改,我建议在TABLE3上建立相关的索引,可以提高你的查询速度很多的

#5


给table2加pk,这样判断重复会很快
给table3加索引,提高查询效率。查一个记录就6/7分钟,也太恐怖了点

#6


这个应该是在1W条数据分解为4-5W条数据后,将这4-5W条写入数据库的一张临时表中更加合适,然后通过与TABLE2的LEFT JOIN方式来更新数据,这个应该会快些。

至于TABLE3的guid数据,关系是肯定有的,这个不应该成为什么问题,至于查询慢,索引有效应用了吗?

#7


6楼的左连接是一个好思路,可以省去每次写入TABLE2的时候都去查询判断有没有相同的记录,但是这样增加了写临时表的额外开销,会不会得不偿失?如果TABLE2有PK的话还是用PK约束比较方便有效

#8


感觉再怎么作也没有办法。

#9


Table2有多少数据

#10


按你的说法,瓶颈在table3,详细说说你的表及其之间的关系和处理方式。

#11


在做平台迁移或应用程序改造,原数据库的初始化工作?

#12


引用 9 楼 viva369 的回复:
Table2有多少数据

Table2的数据源是Table1,也就是把Table1做一些处理后写入Table2

#13


引用 11 楼 kelph 的回复:
在做平台迁移或应用程序改造,原数据库的初始化工作?
相当于平台的改造,升级后的平台不支持以前的数据表,因为设计了新的表结构,所以要把旧的数据表转化成为新的表

#14


1:查询用存储过程。
2:为表建立索引(主要是要用来查询的表)
3:如果可以,添加也放在存储过程。
就是用存储过程来完成添加,也完成从table3表中。

我有如下经历,供你参考:
   1:有个历史纪录表,该表有个nvarchar字段,里面存放的是历史操作,有一定的格式。
   2:该表一个id字段。
   3:该表有个createdatetime字段。
   4:有个字段是放物料编号的。
   5:物料表有上千万。历史记录表也有2千多万。
我要做的事情是,从历史操作中分析某段时间的某个物料的所有进仓数量明细。

我提升性能做法是:
将根据时间查询历史记录表的记录放到临时表中。
然后所有操作都根据临时表来操作。
扩展开来:对数据量大的表,都先根据一定的条件,放到另外一个表中,然后在做操作,就是大表化为小表来操作。
因为sql语句中,查询的过程就是遍历整个表的过程,如果我能事先将不要查询的记录剔除,就可以提高速度。
当然,这是数据量很大的情况。
我经过改善后,对历史记录的查询效率整整提高了70%以上。

#1


可否放在服务端处理数据,数据的判断可否不一条一条处理

#2


引用楼主 sinxy 的帖子:
业务逻辑是这样的: 

1.从数据中的Table1中读取数据到应用程序,对nvarchar字段做一些处理,Table1有4千万条记录,每次读入应用程序大概读取1万条,对这1万条记录处理后,在应用程序中得到4~5倍的记录,也就是4~5万条; 

2.将应用程序中处理后的记录写回数据库的Table2,需要将应用程序中的nvarchar字段写入Table2,但是在写之前需要做判断,如果Table2中有这条记录,就不写入;另外还需要将该nvarchar对应的一个unique…


我个人建议,用某种开发语言自己提取相关数据,然后用循环逐一判断,然后写入表中.

这么大的数据量,估计直接用SQL写会造成内存等的崩溃.

#3


数据逐条判断的时候不要用foreach,要用for比较快效率应该会提高些

#4


引用 2 楼 dawugui 的回复:
引用楼主 sinxy 的帖子:
业务逻辑是这样的:  

1.从数据中的Table1中读取数据到应用程序,对nvarchar字段做一些处理,Table1有4千万条记录,每次读入应用程序大概读取1万条,对这1万条记录处理后,在应用程序中得到4~5倍的记录,也就是4~5万条;  

2.将应用程序中处理后的记录写回数据库的Table2,需要将应用程序中的nvarchar字段写入Table2,但是在写之前需要做判断,如果Table2中有这条记录,就不写入;另外还需要将…

他现在的问题是数据量太大,而又必须要去处理它,所以对其他的环节基本没有什么好的方法,听他的描述我觉得瓶颈应该在对TABLE3的相关处理上,鉴于你对TABLE3做的多是查询工作,比较少的插入和修改,我建议在TABLE3上建立相关的索引,可以提高你的查询速度很多的

#5


给table2加pk,这样判断重复会很快
给table3加索引,提高查询效率。查一个记录就6/7分钟,也太恐怖了点

#6


这个应该是在1W条数据分解为4-5W条数据后,将这4-5W条写入数据库的一张临时表中更加合适,然后通过与TABLE2的LEFT JOIN方式来更新数据,这个应该会快些。

至于TABLE3的guid数据,关系是肯定有的,这个不应该成为什么问题,至于查询慢,索引有效应用了吗?

#7


6楼的左连接是一个好思路,可以省去每次写入TABLE2的时候都去查询判断有没有相同的记录,但是这样增加了写临时表的额外开销,会不会得不偿失?如果TABLE2有PK的话还是用PK约束比较方便有效

#8


感觉再怎么作也没有办法。

#9


Table2有多少数据

#10


按你的说法,瓶颈在table3,详细说说你的表及其之间的关系和处理方式。

#11


在做平台迁移或应用程序改造,原数据库的初始化工作?

#12


引用 9 楼 viva369 的回复:
Table2有多少数据

Table2的数据源是Table1,也就是把Table1做一些处理后写入Table2

#13


引用 11 楼 kelph 的回复:
在做平台迁移或应用程序改造,原数据库的初始化工作?
相当于平台的改造,升级后的平台不支持以前的数据表,因为设计了新的表结构,所以要把旧的数据表转化成为新的表

#14


1:查询用存储过程。
2:为表建立索引(主要是要用来查询的表)
3:如果可以,添加也放在存储过程。
就是用存储过程来完成添加,也完成从table3表中。

我有如下经历,供你参考:
   1:有个历史纪录表,该表有个nvarchar字段,里面存放的是历史操作,有一定的格式。
   2:该表一个id字段。
   3:该表有个createdatetime字段。
   4:有个字段是放物料编号的。
   5:物料表有上千万。历史记录表也有2千多万。
我要做的事情是,从历史操作中分析某段时间的某个物料的所有进仓数量明细。

我提升性能做法是:
将根据时间查询历史记录表的记录放到临时表中。
然后所有操作都根据临时表来操作。
扩展开来:对数据量大的表,都先根据一定的条件,放到另外一个表中,然后在做操作,就是大表化为小表来操作。
因为sql语句中,查询的过程就是遍历整个表的过程,如果我能事先将不要查询的记录剔除,就可以提高速度。
当然,这是数据量很大的情况。
我经过改善后,对历史记录的查询效率整整提高了70%以上。