MySQL快速对比数据技巧

吾爱主题 阅读:106 2024-04-05 13:59:52 评论:0

MySQL运维中,研发同事想对比下两个不同实例上的数据并找出差异,除主键外还需要对比每一个字段,如何做呢?

第一种方案,写程序将两个实例上的每一行数据取出来进行对比,理论可行,但是对比时间较长。

第二种方案,对每一行数据所有字段合并起来,取checksum值,再按照checksum值对比,看着可行,尝试下。

首先要合并所有字段的值,选用MySQL提供的CONCAT函数,如果CONCAT函数中包含NULL值,会导致最终结果为NULL,因此需要使用IFNULL函数来替换NULL值,如:

?
1 CONCAT(IFNULL(C1, '' ),IFNULL(C2, '' ))

加入表有很多行,手动拼个脚本比较累,别急,可以使用information_schema.COLUMNS来处理:

?
1 2 3 4 5 ## 获取列名的拼接串 SELECT GROUP_CONCAT( 'IFNULL(' ,COLUMN_NAME, ',' '' ')' ) FROM information_schema.COLUMNS WHERE TABLE_NAME= 'table_name' ;

假设我们有测试表:

?
1 2 3 4 5 6 CREATE TABLE t_test01 (   id INT AUTO_INCREMENT PRIMARY KEY ,   C1 INT ,   C2 INT )

我们便可以拼接出下面的SQL:

?
1 2 3 4 5 6 7 8 SELECT id, MD5(CONCAT( IFNULL(id, '' ), IFNULL(c1, '' ), IFNULL(c2, '' ), )) AS md5_value FROM t_test01

在两个实例上执行下,然后把结果使用beyond compare对比下,就很容易找出不相同的行以及主键ID

对于数据量较大的表,执行出来的结果集也很大,对比起来比较费劲,那就先尝试缩小结果集,可以将多行记录的md5值合并起来求MD5值,如果最后MD5值相同,则这些行相同,如果不同,则证明存在差异,再按照这些行进行逐行对比。

假设我们按照1000行一组来进行对比,如果需要将分组后的结果合并,需要使用GROUP_CONCAT函数,注意在GROUP_CONCAT函数中添加排序保证合并数据的顺序, SQL如下:

?
1 2 3 4 5 6 7 8 9 10 11 12 13 SELECT min (id) as min_id, max (id) as max_id, count (1) as row_count, MD5(GROUP_CONCAT( MD5(CONCAT( IFNULL(id, '' ), IFNULL(c1, '' ), IFNULL(c2, '' ), )) ORDER BY id )) AS md5_value FROM t_test01 GROUP BY (id div 1000)

执行结果为:

?
1 2 3 4 5 min_id  max_id  row_count  md5_value 0    999    1000     7d49def23611f610849ef559677fec0c 1000   1999    1000     95d61931aa5d3b48f1e38b3550daee08 2000   2999    1000     b02612548fae8a4455418365b3ae611a 3000   3999    1000     fe798602ab9dd1c69b36a0da568b6dbb

当差异数据较少时,即使需要对比上千万数据,我们可以轻松根据根据min_id和max_id来快速定位到哪1000条数据里存在差异,再进行逐行MD5值对比,最终找到差异行。

最终对比图:

PS:

在使用GROUP_CONCAT时,需要配置MySQL变量group_concat_max_len,默认值为1024,超出部分会被阶段。

原文链接:https://www.cnblogs.com/TeyGao/p/8414657.html

可以去百度分享获取分享代码输入这里。
声明

1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,请转载时务必注明文章作者和来源,不尊重原创的行为我们将追究责任;3.作者投稿可能会经我们编辑修改或补充。

【腾讯云】云服务器产品特惠热卖中
搜索
标签列表
    关注我们

    了解等多精彩内容