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值对比,最终找到差异行。
最终对比图:

MySQL —— 如何快速对比数据?的更多相关文章
- MySQL如何快速插入数据
前言: 日常学习和工作中,经常会遇到导数据的需求.比如数据迁移.数据恢复.新建从库等,这些操作可能都会涉及大量数据的导入.有时候导入进度慢,电脑风扇狂转真的很让人崩溃,其实有些小技巧是可以让导入更快速 ...
- MySQL--如何快速对比数据
在MySQL运维中,研发同事想对比下两个不同实例上的数据并找出差异,除主键外还需要对比每一个字段,如何做呢? 第一种方案,写程序将两个实例上的每一行数据取出来进行对比,理论可行,但是对比时间较长. 第 ...
- MySQL中快速复制数据表方法汇总
本文将着重介绍两个MySQL命令的组合,它将以原有数据表为基础,创建相同结构和数据的新数据表. 这可以帮助你在开发过程中快速的复制表格作为测试数据,而不必冒险直接操作正在运行 的数据表. 示例如下: ...
- MySQL InnoDB 快速导入数据
今天把需要分析的数据导入到数据库中. 数据将近7000万条,在txt文件中存放,共5.75G.采用Load data infile 导入,最后花了18个小时导入.主要做了以下修改: 1. MySQL优 ...
- mysql迁移之巨大数据量快速迁移方案
mysql迁移之巨大数据量快速迁移方案-增量备份及恢复 --chenjianwen 一.前言: 当mysql库的大小达到几十个G或者上百G,迁移起来是一件非常费事的事情,业务中断,导出导入耗费大量的时 ...
- MySQL 之 LOAD DATA INFILE 快速导入数据
SELECT INTO OUTFILE > help select; Name: 'SELECT' Description: Syntax: SELECT [ALL | DISTINCT | D ...
- Elasticsearch的快速使用——Spring Boot使用Elastcisearch, 并且使用Logstash同步mysql和Elasticsearch的数据
我主要是给出一些方向,很多地方没有详细说明.当时我学习的时候一直不知道怎么着手,花时间找入口点上比较多,你们可以直接顺着方向去找资源学习. 如果不是Spring Boot项目,那么根据Elastics ...
- MySQL 分区表原理及数据备份转移实战
MySQL 分区表原理及数据备份转移实战 1.分区表含义 分区表定义指根据可以设置为任意大小的规则,跨文件系统分配单个表的多个部分.实际上,表的不同部分在不同的位置被存储为单独的表.用户所选择的.实现 ...
- MySQL批量插入大量数据方法
在MySQL数据库中,如果要插入上百万级的记录,用普通的insert into来操作非常不现实,速度慢人力成本高,推荐使用Load Data或存储过程来导入数据,我总结了一些方法分享如下,主要基于My ...
随机推荐
- python相对包导入报“Attempted relative import in non-package”错误
文章是从stackoverflow翻译过来的,原文地址:Relative imports for the billionth time 本文要在原理上解决 python当中相对包导入出现的问题. 问 ...
- Linux下使用ping出现destination is unreachable的问题可能性
ping时出现request time out和destination is unreachable request time out是指icmp包发出后,长时间没有回应,所以会产生request t ...
- Swift基础类型
1.使用 let 来声明常量,使用 var 来声明变量. 注:你能够在一行中声明多个常量或者多个变量.用逗号隔开. 2.类型标注 假设初始值没有提供足够的信息(或者没有初始值),那你须要在变量后面声明 ...
- linux查看进程和线程的命令
1.任务:获得进程信息 :ps命令,或者top命令,它能显示当前运行中进程的相关信息,包括进程的PID. ps命令能提供一份当前进程的快照.如果想状态可以自动刷新,可以使用top命令. 2.任务:获得 ...
- andriod 下一个页面
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); s ...
- Ext的表格控件如何绑定
1. XML数据源 假设我们有一个数据源是以XML的形式存在的,我们需要从里面取出数据并绑定在界面.XML的结构如下: </age> <name>石曼迪</name&g ...
- [Todo] solr, lucence等学习
先参考这个吧 http://www.shareditor.com/blogshow/6
- 什么是vBlock
Vblock产品是指一种建立系统的方式,Vblock提供的是一个集成包,是一种完整的IT基础架构,并不是一个具体的设备. 具体点就是:Vblock是一个融合了思科服务器与网络.EMC存储系统与管理软件 ...
- 图片变换【Matrix】矩阵 简介
Matrix矩阵介绍 官方文档地址:https://developer.android.com/reference/android/graphics/Matrix.html 在Android中,对图片 ...
- Android -- 发送Broadcast、有序无序
普通广播 优缺点:和有序广播的优 ...