2个百万行级别的表,如何在mysql中比对a表有、b表没有?

zerov 发布于 2017/05/14 10:23
阅读 665
收藏 1

在mysql中,有a、b两表,字段相同,但内容有差异,且两表都达200万行之多,通过下列命令,:

select a.id from a left join b on a.id=b.id where b.id is null;

比对a表有id、b表没有时,运行几分钟后报"lost connection during query",也按度娘的各种建议做过优化,还是无解,求大师指点。

加载中
0
风翔飞
风翔飞

这种情况可以用not exists来筛选。

select a.id from a where not exists(select 1 from b where a.id=b.id );

zerov
zerov
这样,确实很快能查出来,谢谢。
风翔飞
风翔飞
回复 @ManderSY : 比用where b.id is null判断好得多
风翔飞
风翔飞
回复 @ManderSY : not exists 属于普通的联表查询,你加好索引,其实很快的你可以用explain看下。
ManderSF
ManderSF
not exists 性能也不行吧
0
Sean!Zen
Sean!Zen

个人觉得,不要ab表进行left join,可以试一下,把a和b表的id先select出来,只连接这两个表的id字段。

0
Sean!Zen
Sean!Zen

如果是一次性的统计分析,建议新建a_id和b_id两个表,对应存储a和b的两个表的id。然后,分析这两张表的id差异。

Sean!Zen
Sean!Zen
回复 @zerov : 忽然想到一个问题,新建的2表,id字段你是否加索引?如果没有,请先加索引试试
Sean!Zen
Sean!Zen
回复 @zerov : 按照你目前的说法,left join肯定是不行了,要想其他办法解决
zerov
zerov
按你的方法,新建2表只保留id,再用left join比对,还是不行。拆成几段,还是报错。
zerov
zerov
谢谢,先按此试试看
0
开源中国首席罗纳尔多
开源中国首席罗纳尔多

这么大left join会卡死掉吗?

zerov
zerov
百分百的死
0
A_NOOB
A_NOOB

1、可以用solr es之类的搜索引擎或者内存数据库,查询比数据库快些。

2、如果有时间戳一类的字段,可以并行查询各个时间段然后再合并,结果集抽象成主键:内容md5的形式,200w的量级可以多进程读取加入一个进程级缓存,底层采用类似ConcurrentHashMap实现,先把一个结果集丢进去,然后第二个结果集分批次并行的put进去,put的时候可以自己来区分下设置的value,比如比较相等的就put(key,‘eq’)不等的put(key,'ne'),然后未比较的就是之前的老数据,之后可以调换两个map再来一次。

当然,200w行数据库索引建的好的话,sql本身就可以完成,并且比程序实现的比较要快的。

0
Sean!Zen
Sean!Zen

1、按照b表的id字段,创建b_id表,后把b表id导入此表,然后给b_id表加一个标识字段flag(int),设置为0
#####
2、按照a表的id字段,创建a_id表,后把a表id导入此表,然后给a_id表加同样的标识字段flag(int),设置为1
#####
3、把a_id表的数据导入到b_id表,注意忽略重复值id,导入后,给b_id表的flag字段加索引,查询flag=1的就是b表与a表的差异。
#####
(注意:我不知道MySQL如何忽略重复值插入,但是SQLServer有)

0
北极心
北极心

 

 

 

两个2百万的表大么?

北极心
北极心
索引用的得当应该是木问题的
0
zerov
zerov

这索引没错吧?

0
酒逍遥
酒逍遥

select * from a where id not in (select id from b); a 表 b 表加好索引就行

gaomq
gaomq
你这一个in就直接废掉了
返回顶部
顶部