`
tou3921
  • 浏览: 68021 次
  • 性别: Icon_minigender_1
  • 来自: 郑州
社区版块
存档分类
最新评论

向大数据数据库中插入值时,还要判断插入是否重复,然后插入。如何提高效率

阅读更多
向大数据数据库中插入值时,还要判断插入是否重复,然后插入。如何提高效率。
每次insert时还要select下,现在数据库里的数据已有几十万条,这样批量插入的时候效率就会很低,不得不这么做,谁有好的方法。
想过把关键内容取来放在map或者list里,然后每次从集合里判断,可这样内存就吃不消了。
...........
分享到:
评论
103 楼 xiesg 2008-09-23  
先给个建议,如果用Oracle,去看看Merge语句吧
102 楼 Jekey 2008-09-23  
问题的关键是,你判断重复的条件是什么?insert into 的时候把where 条件写足了,把要插入的和原表里边有的数据排除掉不就得了。
101 楼 yinjh 2008-09-22  
1 为什么会有这样的业务需求?数据库建模是否有不合理的地方?
2 是不是可以用人工主键来避免这样的判断?
3 加索引
100 楼 gherb 2008-09-21  
这个貌似是设计上的问题吧?不想想问题跟本出在哪?你这样修修补补得到什么时候?

我觉得按你目前的情况:
1 添加索引 设置索引并定期rebuild
2 分段存储。拆它10几20个表。按规则存。

还有性能问题,那就得拼人品了。我觉着人品有时候很重要。 

tou3921 写道
向大数据数据库中插入值时,还要判断插入是否重复,然后插入。如何提高效率。
每次insert时还要select下,现在数据库里的数据已有几十万条,这样批量插入的时候效率就会很低,不得不这么做,谁有好的方法。
想过把关键内容取来放在map或者list里,然后每次从集合里判断,可这样内存就吃不消了。
...........

99 楼 cuiyi.crazy 2008-09-20  
goolcona 写道
1. insert into _tmp;
2. insert into _table (select * from _tmp t where not exists (select 'x' from _table where _id=t._id));

这个是上面很多一致思路的更简洁的做法了
not in就哭了,not exists不清楚,不过firebird的优化建议是不要用not in而用not exists
98 楼 cuiyi.crazy 2008-09-20  
quanwei309 写道
必须加唯一约束,有的用户在大量并发时段开两个窗口,同时提交,同时查询时数据库都没有这条记录,结果在间隔非常短的时间都入库了。

这个是乐观锁的事
97 楼 cuiyi.crazy 2008-09-20  
vvgg 写道


如果是实时的这样还不如直接select count(*)  然后 insert 快

如果不实时怎么保证数据的一实时性,用户insert 以后,马上可以看到

这个过程是一个一体化过程,并没有多久之后才执行下一步的间隔
所以这个实时性不需要担心;

就像你在界面做一个插入,然后刷新提取一样;是一个连续的无间隔的动作
96 楼 cuiyi.crazy 2008-09-20  
yunjingxinwu 写道
方法2:写trigger,在插入之前做一个查询,如果有就抛弃,没有就插入数据


这个方法比较好,很实用

每一条数据都要做一个select,和你自己写程序select然后insert区别大么?
很可怕的就是锁....

临时表的好处就是最大程度的降低了锁的频率
95 楼 wjs0702cn 2008-09-19  
wolfbrood 写道
vvgg 写道
设为主键,重复捕捉异常

坚决反对这种用法,异常不能这么用,每次异常都会消耗系统很多资源。

方法1:就是先把数据插入一个临时表,然后通过sql找出临时表里面哪些数据在正式表里面没有,然后把这些数据插入正式表。至于怎么找没有重复的数据那就是你的事,数据库存储过程可以完成,也可以写程序一条一条的读出。
这个方法避免了每次插入都要查找一次,但不一样的数据就要插入两次。至于效率问题你可以自己慢慢调优。

方法2:写trigger,在插入之前做一个查询,如果有就抛弃,没有就插入数据


那如果是这样一种情况:
用户注册,要判断用户名在数据库里是否存在,方法1就没有意义了
94 楼 quanwei309 2008-09-19  
必须加唯一约束,有的用户在大量并发时段开两个窗口,同时提交,同时查询时数据库都没有这条记录,结果在间隔非常短的时间都入库了。
93 楼 icewubin 2008-09-18  
cary1130 写道
hocus 写道
bluemeteor 写道
异常不是这么用滴!

做好索引,select count(*)来判断才是正道

我也同意
异常不应该被用于流程和业务逻辑判断


好像select count(1)效率会更高


大部分情况下是一样,你可以上网搜一下,有一篇专门讲count(*)和count(1)的区别的,建议用count(*)。
92 楼 goolcona 2008-09-18  
1. insert into _tmp;
2. insert into _table (select * from _tmp t where not exists (select 'x' from _table where _id=t._id));
91 楼 elmar 2008-09-18  
cary1130 写道
hocus 写道
bluemeteor 写道
异常不是这么用滴!

做好索引,select count(*)来判断才是正道

我也同意
异常不应该被用于流程和业务逻辑判断


好像select count(1)效率会更高


效率无疑是直接插入捕捉异常是最高效率的,
select 1 from TABLE where COL=somevalue limit 1 (mysql)
if RESULT_SET is empty
    insert ...

这样是避免异常的写法。但是这样会产生两次IO,而且整个操作需要锁表。

而这个时候,不妨乐观假设insert操作不产生异常,而直接插入,并丢弃异常。

我觉得这种方案和数据库里的乐观锁的思想是一致的。
90 楼 cary1130 2008-09-17  
hocus 写道
bluemeteor 写道
异常不是这么用滴!

做好索引,select count(*)来判断才是正道

我也同意
异常不应该被用于流程和业务逻辑判断


好像select count(1)效率会更高
89 楼 1986zzrobin 2008-09-17  
update temp_ybqy a set a.yxbz=1 where not exists(select 1 from dj_nsrxx b where b.nsrsbh=a.nsrsbh)

可以把要插入的数据建立一张临时表。然后在用“not exists”比较。效率非常高

88 楼 yunsong 2008-09-17  
找出符合条件的数据,一次性插入
87 楼 winstars 2008-09-17  
tou3921 写道
freeric 写道
cenwenchu 写道
update,命中为0,就insert

支持

这样的话,90%到命中都是1,10%命中0才insert。
这样的话,每条数据还是要对数据库执行两次操作


两边的数据都全部取出来做成两个二维数组,然后通过算法拆分成需要导入的,需要更新的,需要删除的数据,分别执行insert,update和delete,不过内存要求高。。。
86 楼 java小牛 2008-09-17  
wolfbrood 写道
vvgg 写道
设为主键,重复捕捉异常

坚决反对这种用法,异常不能这么用,每次异常都会消耗系统很多资源。

方法1:就是先把数据插入一个临时表,然后通过sql找出临时表里面哪些数据在正式表里面没有,然后把这些数据插入正式表。至于怎么找没有重复的数据那就是你的事,数据库存储过程可以完成,也可以写程序一条一条的读出。
这个方法避免了每次插入都要查找一次,但不一样的数据就要插入两次。至于效率问题你可以自己慢慢调优。

方法2:写trigger,在插入之前做一个查询,如果有就抛弃,没有就插入数据


我暂成“方法1”,我增在一个项目中这样做过,而且业务逻辑比楼主的还要复杂,其中涉及到3个主要的表,一个100多万的数据、另外两个都在50万以上,其中用到了两个临时表,在每次导入2-3万数据的情况下速度还是很快的,更大量的数据导入没有试过,不过这已经满足了我们的业务要求。
85 楼 wl95421 2008-09-16  
用Lucene只是一种方案,或者说是一个建议
并不是一定要用
所以我说,远谈不完美,但是总比自己写算法要来的快,而且在我过去使用的经验,数据库这方面速度,如果不分表的话,不见得比Lucene快,而且Lucene感觉更灵活一些。
个人建议,还是要从自己的实例出发。
适合自己的,才是最好的。
84 楼 elmar 2008-09-16  
引用


我不是都说了吗,其实最根本的东西,还是规模估算。
如果数据量小的话,怎么处理都无所谓,但是现在的数据库已经有几十万条了,如果它的增长量很快,而且重复率比较高,那么就不是一个简单的方案了。
至于说到lucene,其实很简单,因为我觉得根本的问题在于:如何快速判断主键重复,可以演绎成一个如何快速搜索字段的问题,那么Lucene可以解决这个问题,所以我说了可以使用Lucene。
至于Lucene,也远谈不上完美,我只是给出自己的思路,如果真的达到百万甚至更多,那么只使用数据库,就未必是个好的方案。大家不是一定要将精力放在数据库处理或者异常上,而是根据自己实际的情况来选择方案。


判断一个值是否重复,其关键就是搜索,而搜索的关键是排序。
而这些都是任何一个数据库最本质,最核心的任务。
对大量常规数据(包括所有数据库支持的数据类型)的查找,这种数据库最基本的功能,除非这些数据有很强的特性可以自己写一个搜索算法,否则,怎么可能有通用的更高效的算法呢(即使有,也肯定是专利,并且被首先应用于数据库了)?

Lucene的作用是给一个长字符串分词,为分好的词做索引——它是用来查验字符串相似/包含而不是验证相等的。




相关推荐

Global site tag (gtag.js) - Google Analytics