我用的数据库树mysql,有两张表分别是A表跟B表,两张表分别在不同的数据库,有900多个字段,数据为10万条。
B表里面的数据是从A表里迁移过去的,为了防止数据丢失和数据在迁移的过程中出错,所以我需要做一个小程序进行验证。
这里我的程序是写出来了,但是性能很差,检测每个字段下面的数据需要1分多钟.....
我想请教各位高手提出你们宝贵的意见,还有一点我要说的就是我使用 JAVA 的 JDBC 来连接数据库的
希望能够说的稍微详细点,大概需要用多少时间请标明
谢谢各位大虾了
41 个解决方案
#1
900个字段10万条数据,验证完毕1分钟多,算是快的了。
#2
Mark 准备记笔记
#3
如果只是数据迁移的话就不要走java这个层了。直接数据库操作就可以了,数据库之间的远程导入。
#4
朋友我是说 验证一列数据需要1分多钟,
一共有 900多列数据需要验证,
一共有 900多列数据需要验证,
#5
A与B取dump比较.
#6
你一列一列比较得多少个SELECT? 为何不都取出来比较?
想优化的话就是减少SELECT的次数.
想优化的话就是减少SELECT的次数.
#7
回复3楼的朋友:
数据迁移的问题不用考虑,现在我要做的就是进行验证迁移后的数据,有没有办法提高检测效率
#8
建议在数据层解决。重新考虑业务逻辑。
如果可以,尝试一下MSsql2005/2008的镜像服务器
如果可以,尝试一下MSsql2005/2008的镜像服务器
#9
在迁移的时候在存储过程顺便就做数据验证过滤了
#10
占楼学习
#11
朋友你讲的很对,不过这不是我考虑的,现在摆在我面前的问题是对这10W 条数据验证进行优化
#12
建议一行一行的验证.按照LZ描述,一列验证花了1分钟。那么一行的一个字段验证为 1/10万 分钟,里面还有去SELECT的时间,假设一次SELECT的时间占一次验证的4/5,按行验证算下来总共要花的时间1*4/5 + 1/5*900 = 180.8分钟 = 3小时。
#13
朋友你说的有道理
我一列一列的取是防止中间数据丢失会有问题,我感觉是应为我的java 代码写的不够好
有没有这方面的意见?
#14
可不可以用多台机器来验证呢
如果使用多台机器, 每台机器平均分配需要验证的行数, 这样时间就可以大大的节省了吧
如果使用多台机器, 每台机器平均分配需要验证的行数, 这样时间就可以大大的节省了吧
#15
刚刚回复的又丢,,,看看用连接池吧,,先把数据提到内存中,,然后用尽可能少的SELECT语句进行验证,,试试看
#16
我有点没看清楚,为什么要一行一行?总共有10万行啊....select要10万次
但是列的话只有 900多列,我也才select 900多次!!
能不能说明白点?
#17
关键在于多次从数据库取数据降低效率
从B取所有数据,缓存,ID单独保存之int数组B_IDsARR[]
然后:
StringBuffer B_IDs = new StringBuffer(B_IDsARR[0]);
for(int i = 1; i < B_IDsARR.length; i++)
B_IDs.append(" , " + B_IDsARR[i]);
"select x,x,x,x…… form A where id in " + B_IDs.toString();
现在想随你折腾吧
从B取所有数据,缓存,ID单独保存之int数组B_IDsARR[]
然后:
StringBuffer B_IDs = new StringBuffer(B_IDsARR[0]);
for(int i = 1; i < B_IDsARR.length; i++)
B_IDs.append(" , " + B_IDsARR[i]);
"select x,x,x,x…… form A where id in " + B_IDs.toString();
现在想随你折腾吧
#18
楼主都需要验证哪些信息啊? 900*10万 个元素都要一一对比吗 ?是不不是每个元素都要验证,有必要吗?
#19
"select x,x,x,x…… form A where id in ( " + B_IDs.toString() + " )";
#20
一列一列的取的话,尽管才有900多SELECT,不过每个SELECT传输的数据是很惊人的.
你可以分几次全取:
select * from table order by id LIMIT 1000 OFFSET 0
select * from table order by id LIMIT 1000 OFFSET 1000
select * from table order by id LIMIT 1000 OFFSET 2000
select * from table order by id LIMIT 1000 OFFSET 3000
可以调整LIMIT和OFFSET的值,这些SELECT也可以分配到几台机器同时执行.
我还是认为用mysql_dump把表格弄出来比较的话最快,时间都浪费到传数据上了.
你可以分几次全取:
select * from table order by id LIMIT 1000 OFFSET 0
select * from table order by id LIMIT 1000 OFFSET 1000
select * from table order by id LIMIT 1000 OFFSET 2000
select * from table order by id LIMIT 1000 OFFSET 3000
可以调整LIMIT和OFFSET的值,这些SELECT也可以分配到几台机器同时执行.
我还是认为用mysql_dump把表格弄出来比较的话最快,时间都浪费到传数据上了.
#21
对都需要验证,而且还不能出一点问题
#22
首先想说的就是 你的分页读取还是可取的,希望还有别的意见,
还有就是只能在一台机子上执行
#23
费时主要在两方面
1.SELECT特定的字段要比SELECT *费时,因为要做查找.
2.数据传输费时.
1的话没办法再简单了.
2的话你可以把900个字段做个检验码,比如说每个字段取md5码头3位连到一起,这样基本是不会出错而且传送量大减.
1.SELECT特定的字段要比SELECT *费时,因为要做查找.
2.数据传输费时.
1的话没办法再简单了.
2的话你可以把900个字段做个检验码,比如说每个字段取md5码头3位连到一起,这样基本是不会出错而且传送量大减.
#24
.
#25
MySQl 不太了解。。。
Tsql有发布订阅功能。。。不错。。。。
Tsql有发布订阅功能。。。不错。。。。
#26
建设你换ORACLE,完全可以解决了
#27
我现在是通过Map把某一列的值存起来,把id存在key里,再去通过id取,
你能不能把你的代码提供出来供我参考下,
#28
这个问题值得学习!
#29
学习····
#30
学习~
#31
mark
#32
SELECT CONCAT(LEFT(md5(字段1),3), LEFT(md5(字段2),3),...) FROM table;
当然这个SQL用程序自动生成。
当然这个SQL用程序自动生成。
#33
用多线程分页读取 应该会快点吧
#34
建议LZ把字段联合起来,不要900个列就比较900多次,不仅效率低,而且超级麻烦。
既然是要验证,那么只要判断是对还是错就行了!
既然是要验证,那么只要判断是对还是错就行了!
#35
按你的算法,字段间要用特列字符作分隔,否则会有可能
'abcde' + 'fgh' == 'abc' + 'defgh'
#36
留名学习
#37
900个字段10万条数据,验证完毕1分钟多,算是快的了
#38
一个思路,至于具体的拼法,就让LZ自己考虑好了!
这个兄弟的补充还好,的确存在这样的可能!
#39
咱别说是900个字段了,就是900条数据查询还要一段时间。
#40
其实各位说的都有道理,
总的归纳为这么几种办法:
(1)分批读取数据在JAVA里进行处理
(2)加上线程进行处理
大概思路都差不多,但是具体的实现的细节能不能贴出来,贴出代码如果要是满意的话悬赏80分,另外还有20分给予想法有创意的朋友们
总的归纳为这么几种办法:
(1)分批读取数据在JAVA里进行处理
(2)加上线程进行处理
大概思路都差不多,但是具体的实现的细节能不能贴出来,贴出代码如果要是满意的话悬赏80分,另外还有20分给予想法有创意的朋友们
#41
一台机器的话加上多线程反而overhead增加,如果不是多核反而会变慢。
建议就开两个线程从A,B里取,
每个线程就一个SELECT:
SELECT CONCAT(LEFT(md5(字段1),3), LEFT(md5(字段2),3),...,LEFT(md5(字段900),3)) as verify_code FROM table;
这样拿过来以后10万的循环,每次比较的字符串长度是3×90=270字节。
从一台mysql传输的数据量是270Byte×10万=27M,如果md5就取一位会是9M,但精度下降。
建议就开两个线程从A,B里取,
每个线程就一个SELECT:
SELECT CONCAT(LEFT(md5(字段1),3), LEFT(md5(字段2),3),...,LEFT(md5(字段900),3)) as verify_code FROM table;
这样拿过来以后10万的循环,每次比较的字符串长度是3×90=270字节。
从一台mysql传输的数据量是270Byte×10万=27M,如果md5就取一位会是9M,但精度下降。
#1
900个字段10万条数据,验证完毕1分钟多,算是快的了。
#2
Mark 准备记笔记
#3
如果只是数据迁移的话就不要走java这个层了。直接数据库操作就可以了,数据库之间的远程导入。
#4
朋友我是说 验证一列数据需要1分多钟,
一共有 900多列数据需要验证,
一共有 900多列数据需要验证,
#5
A与B取dump比较.
#6
你一列一列比较得多少个SELECT? 为何不都取出来比较?
想优化的话就是减少SELECT的次数.
想优化的话就是减少SELECT的次数.
#7
回复3楼的朋友:
数据迁移的问题不用考虑,现在我要做的就是进行验证迁移后的数据,有没有办法提高检测效率
#8
建议在数据层解决。重新考虑业务逻辑。
如果可以,尝试一下MSsql2005/2008的镜像服务器
如果可以,尝试一下MSsql2005/2008的镜像服务器
#9
在迁移的时候在存储过程顺便就做数据验证过滤了
#10
占楼学习
#11
朋友你讲的很对,不过这不是我考虑的,现在摆在我面前的问题是对这10W 条数据验证进行优化
#12
建议一行一行的验证.按照LZ描述,一列验证花了1分钟。那么一行的一个字段验证为 1/10万 分钟,里面还有去SELECT的时间,假设一次SELECT的时间占一次验证的4/5,按行验证算下来总共要花的时间1*4/5 + 1/5*900 = 180.8分钟 = 3小时。
#13
朋友你说的有道理
我一列一列的取是防止中间数据丢失会有问题,我感觉是应为我的java 代码写的不够好
有没有这方面的意见?
#14
可不可以用多台机器来验证呢
如果使用多台机器, 每台机器平均分配需要验证的行数, 这样时间就可以大大的节省了吧
如果使用多台机器, 每台机器平均分配需要验证的行数, 这样时间就可以大大的节省了吧
#15
刚刚回复的又丢,,,看看用连接池吧,,先把数据提到内存中,,然后用尽可能少的SELECT语句进行验证,,试试看
#16
我有点没看清楚,为什么要一行一行?总共有10万行啊....select要10万次
但是列的话只有 900多列,我也才select 900多次!!
能不能说明白点?
#17
关键在于多次从数据库取数据降低效率
从B取所有数据,缓存,ID单独保存之int数组B_IDsARR[]
然后:
StringBuffer B_IDs = new StringBuffer(B_IDsARR[0]);
for(int i = 1; i < B_IDsARR.length; i++)
B_IDs.append(" , " + B_IDsARR[i]);
"select x,x,x,x…… form A where id in " + B_IDs.toString();
现在想随你折腾吧
从B取所有数据,缓存,ID单独保存之int数组B_IDsARR[]
然后:
StringBuffer B_IDs = new StringBuffer(B_IDsARR[0]);
for(int i = 1; i < B_IDsARR.length; i++)
B_IDs.append(" , " + B_IDsARR[i]);
"select x,x,x,x…… form A where id in " + B_IDs.toString();
现在想随你折腾吧
#18
楼主都需要验证哪些信息啊? 900*10万 个元素都要一一对比吗 ?是不不是每个元素都要验证,有必要吗?
#19
"select x,x,x,x…… form A where id in ( " + B_IDs.toString() + " )";
#20
一列一列的取的话,尽管才有900多SELECT,不过每个SELECT传输的数据是很惊人的.
你可以分几次全取:
select * from table order by id LIMIT 1000 OFFSET 0
select * from table order by id LIMIT 1000 OFFSET 1000
select * from table order by id LIMIT 1000 OFFSET 2000
select * from table order by id LIMIT 1000 OFFSET 3000
可以调整LIMIT和OFFSET的值,这些SELECT也可以分配到几台机器同时执行.
我还是认为用mysql_dump把表格弄出来比较的话最快,时间都浪费到传数据上了.
你可以分几次全取:
select * from table order by id LIMIT 1000 OFFSET 0
select * from table order by id LIMIT 1000 OFFSET 1000
select * from table order by id LIMIT 1000 OFFSET 2000
select * from table order by id LIMIT 1000 OFFSET 3000
可以调整LIMIT和OFFSET的值,这些SELECT也可以分配到几台机器同时执行.
我还是认为用mysql_dump把表格弄出来比较的话最快,时间都浪费到传数据上了.
#21
对都需要验证,而且还不能出一点问题
#22
首先想说的就是 你的分页读取还是可取的,希望还有别的意见,
还有就是只能在一台机子上执行
#23
费时主要在两方面
1.SELECT特定的字段要比SELECT *费时,因为要做查找.
2.数据传输费时.
1的话没办法再简单了.
2的话你可以把900个字段做个检验码,比如说每个字段取md5码头3位连到一起,这样基本是不会出错而且传送量大减.
1.SELECT特定的字段要比SELECT *费时,因为要做查找.
2.数据传输费时.
1的话没办法再简单了.
2的话你可以把900个字段做个检验码,比如说每个字段取md5码头3位连到一起,这样基本是不会出错而且传送量大减.
#24
.
#25
MySQl 不太了解。。。
Tsql有发布订阅功能。。。不错。。。。
Tsql有发布订阅功能。。。不错。。。。
#26
建设你换ORACLE,完全可以解决了
#27
我现在是通过Map把某一列的值存起来,把id存在key里,再去通过id取,
你能不能把你的代码提供出来供我参考下,
#28
这个问题值得学习!
#29
学习····
#30
学习~
#31
mark
#32
SELECT CONCAT(LEFT(md5(字段1),3), LEFT(md5(字段2),3),...) FROM table;
当然这个SQL用程序自动生成。
当然这个SQL用程序自动生成。
#33
用多线程分页读取 应该会快点吧
#34
建议LZ把字段联合起来,不要900个列就比较900多次,不仅效率低,而且超级麻烦。
既然是要验证,那么只要判断是对还是错就行了!
既然是要验证,那么只要判断是对还是错就行了!
#35
按你的算法,字段间要用特列字符作分隔,否则会有可能
'abcde' + 'fgh' == 'abc' + 'defgh'
#36
留名学习
#37
900个字段10万条数据,验证完毕1分钟多,算是快的了
#38
一个思路,至于具体的拼法,就让LZ自己考虑好了!
这个兄弟的补充还好,的确存在这样的可能!
#39
咱别说是900个字段了,就是900条数据查询还要一段时间。
#40
其实各位说的都有道理,
总的归纳为这么几种办法:
(1)分批读取数据在JAVA里进行处理
(2)加上线程进行处理
大概思路都差不多,但是具体的实现的细节能不能贴出来,贴出代码如果要是满意的话悬赏80分,另外还有20分给予想法有创意的朋友们
总的归纳为这么几种办法:
(1)分批读取数据在JAVA里进行处理
(2)加上线程进行处理
大概思路都差不多,但是具体的实现的细节能不能贴出来,贴出代码如果要是满意的话悬赏80分,另外还有20分给予想法有创意的朋友们
#41
一台机器的话加上多线程反而overhead增加,如果不是多核反而会变慢。
建议就开两个线程从A,B里取,
每个线程就一个SELECT:
SELECT CONCAT(LEFT(md5(字段1),3), LEFT(md5(字段2),3),...,LEFT(md5(字段900),3)) as verify_code FROM table;
这样拿过来以后10万的循环,每次比较的字符串长度是3×90=270字节。
从一台mysql传输的数据量是270Byte×10万=27M,如果md5就取一位会是9M,但精度下降。
建议就开两个线程从A,B里取,
每个线程就一个SELECT:
SELECT CONCAT(LEFT(md5(字段1),3), LEFT(md5(字段2),3),...,LEFT(md5(字段900),3)) as verify_code FROM table;
这样拿过来以后10万的循环,每次比较的字符串长度是3×90=270字节。
从一台mysql传输的数据量是270Byte×10万=27M,如果md5就取一位会是9M,但精度下降。