MySQL快速对比数据技巧

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

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

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

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

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

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

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

假设我们有测试表:

CREATE TABLE t_test01
(
 id INT AUTO_INCREMENT PRIMARY KEY,
 C1 INT,
 C2 INT
)

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

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如下:

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)

执行结果为:

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,超出部分会被阶段。

(0)

相关推荐

  • mysql 5.7.20常用下载、安装和配置方法及简单操作技巧(解压版免安装)

    话说凌晨刚折腾完一台MySQL 5.7.19版本的安装,未曾料到早上MySQL官方就发布了最新的5.7.20版本.这个版本看似更新不多,但是加入了一个我们所急需的功能. MySQL 5.7.20版本新增了参数group-replication-member-weight,用来表示选主时服务器的优先级.若没有这个优先级,则之前版本的MGR会选择一个或许不是用户想要的节点,这是一个令人头疼的问题.相信5.7.20版本新增的该参数能解决一些用户的痛点. 1. 下载: mysql-5.7.20是解压版免

  • MySQL数据库常用操作技巧总结

    本文实例总结了MySQL数据库常用操作技巧.分享给大家供大家参考,具体如下: 一.查询不同表中同名字段(表连接查询条件神器) use information_schema; select * from columns where column_name='字段名'; 二.查询记录总数 SELECT SQL_CALC_FOUND_ROWS * FROM TABLE WHERE 1=1; 即可得出总数据行数 SET @RowCount=found_rows(); 三.存储过程数据查询分页 预定义变量

  • 5个保护MySQL数据仓库的小技巧

    汇总各种来源的数据,可以创建一个中央仓库.通过分析和汇总业务数据报告,数据仓库能够帮助企业做出明智.战略性的决策分析.虽然数据仓库提供了许多便利,但是把这些敏感数据收集到一个单独系统,会给数据仓库带来安全问题. 如果选择使用数据仓库,企业需要考虑如何更好地保护内部信息系统.任何数仓安全方面的妥协都会给入侵者或网络罪犯以可乘之机,造成销售.营销.客户信息等业务数据的毁坏泄露.今年爆发的WannaCry勒索软件事件也表明了这一点,现代企业需要严格规避数据犯罪. 在数据仓库中,最常见的数据库管理系统应

  • MySQL注入绕开过滤的技巧总结

    首先来看GIF操作: 情况一:空格被过滤 使用括号()代替空格,任何可以计算出结果的语句,都可以用括号包围起来: select * from(users)where id=1; 使用注释/**/绕过空格: select * from/**/users/**/where id=1; 情况二:限制from与某种字符组合 在from后加个点.即使用from.来代替from: select * from. users where id=1; 再直接看GIF: 说白了,就是将'字段名 '替换成hex: 这

  • 提升MYSQL查询效率的10个SQL语句优化技巧

    MySQL数据库执行效率对程序的执行速度有很大的影响,有效的处理优化数据库是非常有用的.尤其是大量数据需要处理的时候. 1. 优化你的MySQL查询缓存 在MySQL服务器上进行查询,可以启用高速查询缓存.让数据库引擎在后台悄悄的处理是提高性能的最有效方法之一.当同一个查询被执行多次时,如果结果是从缓存中提取,那是相当快的. 但主要的问题是,它是那么容易被隐藏起来以至于我们大多数程序员会忽略它.在有些处理任务中,我们实际上是可以阻止查询缓存工作的. // query cache does NOT

  • 利用tcpdump对mysql进行抓包操作技巧

    利用tcpdump对mysql进行抓包操作如下所示: 命令如下: 复制代码 代码如下: tcpdump -s 0 -l -w - dst 192.168.244.10 and port 3306 -i eno16777736 |strings 其中-i指定监听的网络接口,在RHEL 7下,网络接口名不再是之前的eth0,而是 eno16777736. 在RHEL 5&6下,可直接不带-i参数,因为它默认是eth0.在RHEL 7下,如果不用-i参数指定网络接口,则会报如下错误: 复制代码 代码如

  • MySql Sql 优化技巧分享

    有天发现一个带inner join的sql 执行速度虽然不是很慢(0.1-0.2),但是没有达到理想速度.两个表关联,且关联的字段都是主键,查询的字段是唯一索引. sql如下: SELECT p_item_token.*, p_item.product_type FROM p_item_token INNER JOIN p_item ON p_item.itemid = p_item_token.itemid WHERE p_item_token.token ='db87a780427d4d02

  • MySQL使用的常见问题解决与应用技巧汇总

    前言 在MySQL日常开发或者是维护中,有一些问题或是故障往往是难以避免的,如丢失密码.表损坏.在此总结一下常见的问题,以备今后所需. 一. 忘记 MySQL 的 root 密码 1. 登录到数据库所在的服务器,手工 kill 掉 mysql 进程. (1) 登录到数据库所在的服务器,手工 kill 掉 MySQL 进程: root@bogon:/data/mysql# kill `cat ./mysql.pid` 其中,mysql.pid 指的是 MySQL 数据目录下的 pid 文件,它记录

  • 30个mysql千万级大数据SQL查询优化技巧详解

    1.对查询进行优化,应尽量避免全表扫描,首先应考虑在 where 及 order by 涉及的列上建立索引. 2.应尽量避免在 where 子句中对字段进行 null 值判断,否则将导致引擎放弃使用索引而进行全表扫描,如:select id from t where num is null可以在num上设置默认值0,确保表中num列没有null值,然后这样查询:select id from t where num=0 3.应尽量避免在 where 子句中使用!=或<>操作符,否则引擎将放弃使用

  • 分享101个MySQL调试与优化技巧

    MySQL是一个功能强大的开源数据库.随着越来越多的数据库驱动的应用程序,人们一直在推动MySQL发展到它的极限.这里是101条调节和优化MySQL安装的技巧.一些技巧是针对特定的安装环境的,但这些思路是通用的.我已经把他们分成几类,来帮助你掌握更多MySQL的调节和优化技巧. MySQL 服务器硬件和操作系统调节: 1. 拥有足够的物理内存来把整个InnoDB文件加载到内存中--在内存中访问文件时的速度要比在硬盘中访问时快的多. 2. 不惜一切代价避免使用Swap交换分区 – 交换时是从硬盘读

  • Mysql根据时间查询日期的优化技巧

    例如查询昨日新注册用户,写法有如下两种: EXPLAIN select * from chess_user u where DATE_FORMAT(u.register_time,'%Y-%m-%d')='2018-01-25'; EXPLAIN select * from chess_user u where u.register_time BETWEEN '2018-01-25 00:00:00' and '2018-01-25 23:59:59'; register_time字段是date

  • JavaWeb连接数据库MySQL的操作技巧

    数据库是编程中重要的一部分,它囊括了数据操作,数据持久化等各方面.在每一门编程语言中都占有相当大的比例. 本次,我以MySQL为例,使用MVC编程思想(请参阅我之前的博客).简单演示一下JavaWeb对数据库的操作. 1:我们需要掌握简单的SQL语句,并且会简单操作图形化的数据库.我们在数据库建一个表(Users)可以在里面随便添加几条数据. 2:接下来,我们获得驱动并连接到MySQL. package com.joker.web.db; import java.sql.Connection;

随机推荐