求高效算法思路

jdc71264 2012-06-29 01:32:30
现在有个这样的问题,数据库里面有10W条以上的数据,然后现在需要给数据库里面导入数据,我已经将数据读到DataTable里面了,但是再插入之前需要验证,根据某一列值取数据库验证,如果存在这条数据,就不能插入,只插入没有的。
我目前采用的是遍历的方式,但是每次客户导入的时候,数据量都会将近2W条,110个字段,速度感觉有点慢,客户催的急,所以当时也没太多考虑,能导入就行,现在想优化下。
求大神指点思路,代码可以多些,但是速度要快,要效率。
linq就不需要了。
...全文
227 19 打赏 收藏 转发到动态 举报
写回复
用AI写文章
19 条回复
切换为时间正序
请发表友善的回复…
发表回复
wzlblair 2012-07-01
  • 打赏
  • 举报
回复
不知道你这个项目,以及客户的要求是什么?客户的意思是不是导入的过程太漫长了?


我有两种思路:
1、先将数据导入一个临时表,然后调用存储过程慢慢执行。如果110个子段里包含text,xml这些类型的话,可能会非常慢。
2、编写一个服务,把需要导入的数据(比如excel)交给他,让它单独执行一个个插入数据库的过程。这样你以前的代码也都可以用到。 推荐使用这种,只上传文件。还可以备份,免得客户以后跟你扯皮。
jdc71264 2012-07-01
  • 打赏
  • 举报
回复
[Quote=引用 16 楼 的回复:]
10W条以上,还要验证。
可以把压力分以下。
是存储过程分页处理数据,在匹配是考虑用Hashtable。
如果你的dataset relation 玩的好的话,可以ds的函数处理。这个比较多,你自己去网上找下。
[/Quote]
谢谢指导,回头一定学习这个,因为我还没听过你说的这个玩意呢。。。看来对我来说又是个新玩意啊
jdc71264 2012-07-01
  • 打赏
  • 举报
回复
[Quote=引用 15 楼 的回复:]
不知道你这个项目,以及客户的要求是什么?客户的意思是不是导入的过程太漫长了?


我有两种思路:
1、先将数据导入一个临时表,然后调用存储过程慢慢执行。如果110个子段里包含text,xml这些类型的话,可能会非常慢。
2、编写一个服务,把需要导入的数据(比如excel)交给他,让它单独执行一个个插入数据库的过程。这样你以前的代码也都可以用到。 推荐使用这种,只上传文件。还可以备份,免得……
[/Quote]
客户倒是没有说太慢,只是我自己觉得不太完美。。。
现在导入2W条数据的时间大概要3分钟,验证过程2分钟,真正导入大概一分钟这个样子
jdc71264 2012-07-01
  • 打赏
  • 举报
回复
[Quote=引用 14 楼 的回复:]
你导入到datatable本身没问题,使用SqlBulkCopy 会提高一些速度

全部导入到一个导入表里面
然后在 让 Code所在的表 和导入表做 InnerJoin 最后直接在数据库删除inner join的记录即可,用delete from table where

等于只会连接一次数据库,即插入那次,随后的所有操作都在数据库进行
[/Quote]
嗯,不错的建议,回头考虑下,这两天要出差。。。
段传涛 2012-07-01
  • 打赏
  • 举报
回复
10W条以上,还要验证。
可以把压力分以下。
是存储过程分页处理数据,在匹配是考虑用Hashtable。
如果你的dataset relation 玩的好的话,可以ds的函数处理。这个比较多,你自己去网上找下。
  • 打赏
  • 举报
回复
[Quote=引用楼主 的回复:]
现在有个这样的问题,数据库里面有10W条以上的数据,然后现在需要给数据库里面导入数据,我已经将数据读到DataTable里面了
[/Quote]

晕死!看到这里其实往往就不用往下看了......你导入数据到DataTable?那么你知道数据库还有索引吗?你导入了数据库的精华了吗?

你没有在大脑中导入数据按照索引搜索的基本知识啊。
jdc71264 2012-06-30
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 的回复:]

先检查这个字段是否存在,如果不存在,把一条插入记录放到一个list<string>里面,如果存在,不生成插入语句
然后执行一个方法,把数据插入数据库.
/// <summary>
/// 执行多个Sql语句,同时进行事务处理
/// </summary>
/// <param name="querys">sql语句列表</……
[/Quote]
你这个我回头琢磨下,目前我用的是适配器的方式插入的,插入速度还行,就是处理数据这里是个瓶颈,有点慢,1.8W条数据,假如说插入需要1分钟,那么处理这里差不多就要2.5到3分钟的样子
tlerbao 2012-06-30
  • 打赏
  • 举报
回复
哥感觉7楼是正解! 事物处理是必须的!
gsralex 2012-06-30
  • 打赏
  • 举报
回复
你导入到datatable本身没问题,使用SqlBulkCopy 会提高一些速度

全部导入到一个导入表里面
然后在 让 Code所在的表 和导入表做 InnerJoin 最后直接在数据库删除inner join的记录即可,用delete from table where

等于只会连接一次数据库,即插入那次,随后的所有操作都在数据库进行
jdc71264 2012-06-30
  • 打赏
  • 举报
回复
[Quote=引用 11 楼 的回复:]

引用楼主 的回复:
现在有个这样的问题,数据库里面有10W条以上的数据,然后现在需要给数据库里面导入数据,我已经将数据读到DataTable里面了


晕死!看到这里其实往往就不用往下看了......你导入数据到DataTable?那么你知道数据库还有索引吗?你导入了数据库的精华了吗?

你没有在大脑中导入数据按照索引搜索的基本知识啊。
[/Quote]
可能是我理解能力有点差,不是很明白你的意思
我数据库里面的索引是code这个字段,另外还有个oracle数据库的自增列(防止重复数据),dt2里面的每条数据都是标准数据了,就是有些数据数据库里面已经有了,所以我将数据库里面的code字段读了出来放在dt1里面了
请多多指点,小弟不胜感激
showjim 2012-06-30
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 的回复:]

引用 3 楼 的回复:
直接datatable.marge

合并dt就ok了

可能我表达的不够清楚,现在是这么个问题,有个dt1(来自数据库的10W条数据,以后还会更加多,1个字段,假定他叫code),还有个dt2(110个字段,里面也有个code,他是数据的唯一标识),现在的问题是要把dt2导入数据库,导入前需要判断下code是否已经在数据库存在了,存在的话就将dt2里面的这条……
[/Quote]
可以把dt1.code读入内存HashSet,dt2先过滤再倒入
天下在我心 2012-06-29
  • 打赏
  • 举报
回复
补充下,根据你的需求是存在先执行删除,在执行插入,只要把sql语句放在这个list里面就行.
天下在我心 2012-06-29
  • 打赏
  • 举报
回复
先检查这个字段是否存在,如果不存在,把一条插入记录放到一个list<string>里面,如果存在,不生成插入语句
然后执行一个方法,把数据插入数据库.
/// <summary>
/// 执行多个Sql语句,同时进行事务处理
/// </summary>
/// <param name="querys">sql语句列表</param>
/// <returns>成功或失败</returns>
public bool ExecuteSqlWithTransaction(List<string> querys)
{
SqlTransaction trans = null;
//打开连接
if (openConnection())
{
trans = sqlCon.BeginTransaction();
sqlComm = new SqlCommand();
sqlComm.Connection = sqlCon;
sqlComm.Transaction = trans;
try
{
for (int i = 0; i < querys.Count; i++)
{
sqlComm.CommandText = querys[i];
sqlComm.ExecuteNonQuery();
}
trans.Commit();
}
catch (Exception)
{
trans.Rollback();
return false;
}
finally
{
//关闭连接
closeConnection();
}
}
else
{
return false;
}
return true;
}
Handsome__Guy 2012-06-29
  • 打赏
  • 举报
回复
可以先查出DT2的code,以DT2的code为条件查询DT1里有没有数据,如果有的话移除DT2的数据,没有的话不用移除,这样只循环dt2的rows.count次,循环完了以后再批量添加进数据库。
jdc71264 2012-06-29
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 的回复:]
直接datatable.marge

合并dt就ok了
[/Quote]
可能我表达的不够清楚,现在是这么个问题,有个dt1(来自数据库的10W条数据,以后还会更加多,1个字段,假定他叫code),还有个dt2(110个字段,里面也有个code,他是数据的唯一标识),现在的问题是要把dt2导入数据库,导入前需要判断下code是否已经在数据库存在了,存在的话就将dt2里面的这条数据移除掉,即使它的其他字段与这个不同(客户的意思,因为他们也不敢保证他给我的数据是完全正确的)。
如果按照你的意思来的话那问题根本解决不了

哎,烦人啊,想优化下发现好难啊,坐等大神出现。
Mayankai0306 2012-06-29
  • 打赏
  • 举报
回复
估计以后会用到,帮顶

不过话说110个字段也真是够多的.....
wanghui0380 2012-06-29
  • 打赏
  • 举报
回复
直接datatable.marge

合并dt就ok了
jdc71264 2012-06-29
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 的回复:]
2个集合求差集、然后在批量导入。数据库连接只要一次。
[/Quote]
怎么求?
关键是算法。。。
这个思路我也想过
可是首先你需要把datatable里面的数据丢到集合里面去,接着查询数据库里面的10W条数据,然后两个集合求差(关键是怎么个求法,除了遍历,有更效率的方法没)
求差了之后,数据又不完整了,有得从datatable里面移除这些数据,也很麻烦
licai1210 2012-06-29
  • 打赏
  • 举报
回复
2个集合求差集、然后在批量导入。数据库连接只要一次。

62,074

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术交流专区
javascript云原生 企业社区
社区管理员
  • ASP.NET
  • .Net开发者社区
  • R小R
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

.NET 社区是一个围绕开源 .NET 的开放、热情、创新、包容的技术社区。社区致力于为广大 .NET 爱好者提供一个良好的知识共享、协同互助的 .NET 技术交流环境。我们尊重不同意见,支持健康理性的辩论和互动,反对歧视和攻击。

希望和大家一起共同营造一个活跃、友好的社区氛围。

试试用AI创作助手写篇文章吧