日期:2014-05-16  浏览次数:20702 次

mysql算法问题--大流量下找不同点
有两张表a,b里面的数据结构一摸一样,每张表都有5千万条,其中a,b有一条数据有问题,其他一摸一样,如何用高算法找出这条内容??求sql语句,小弟弄了好多,一直不行啊。

------解决方案--------------------
引用1.a,b两张表的一个id不一样了,

------解决方案--------------------
首先对两个表分别进行一次全表扫描,目的是找出不一致的列.方法是类似于select sum(id),avg(hex(name))... from tbl.具体使用哪些函数需要楼主自己斟酌,目的是尽量发现不同之处.
如果两个表的数据完全一样,那么两个查询返回的结果会完全相同;否则就是有不同.
如果不同,不同的列可能有多个,这样最好,因为给我们留下了更多的选择.假设我们的运气好,出问题的列里面包含单列唯一键,比如id列.那么我们只需要进行一次连接,使用楼上各位说的not exists语句
select id from a where not exist(select 1 from b where id=a.id)
因为我们只用了id列,所以这是覆盖索引,执行起来要快很多.查询完毕后就得到了那个不同行的id值~
如果运气差一点,出问题的列中没有单列唯一键,而是多列唯一索引,那么方法同上,不过因为要读取多列,所以速度会慢些,但总还是覆盖索引.
如果运气更差一点,出问题的列中没有唯一键,而只有普通键(某个索引的最左前缀也可以),那就比较棘手了.但愿你使用的是InnoDB存储引擎,因为InnoDB的非主键索引中存储了主键值.假设name列是普通键,那么select id,name from tbl还是可以使用覆盖索引的.此时可以使用ACMAIN_CHM说的语句,此时仍是覆盖索引.如果不是InnoDB,那么就无奈也只能用这个语句了,区别就是无法使用覆盖索引而只好使用表扫描.
如果运气超级差,出问题的列中没有任何键,那也没办法了,还是用ACMAIN_CHM的语句.
上面的这些都是为了利用覆盖索引,最后两种情况没有办法利用覆盖索引,非常无奈.
------解决方案--------------------
写个简单的过程 按照id分批 50万 50万一次的对比 对比的脚本就用3楼的