重磅!10年数据库专家为MySQL填充亿级数据,要不要观摩一下?
liebian365 2025-01-02 17:40 26 浏览 0 评论
为MySQL填充亿级数据---问题描述
在编写代码之前,应先针对业务设计的数据格式创建表结构,然后填充亿级数据,此阶段出现的典型问题如下:
(1)对于新上线的项目,我们希望能测试出它的最高承载用户量,在数据库为空的情况下,应如何增加亿级数据?
(2)在学习和工作工程中,经常需要使用数据量庞大的表来模拟系统在真实环境中的响应情况。如果只写一段代码,之后循环使用INSERT语句插入数据则实在是太慢了,是否有更快速的方法?
问题分析与解决方案
当通过Java、C#、Python等语言对MySQL进行操作时,不仅有语言自身的消耗,还有语言和数据库连接的消耗,所以当想要为数据库增加大量数据时,建议通过中间件或计算机系统对其增加数据量,切勿通过语言连接的方式。
另外,在执行时应尽可能减少事务、链表等相应情况,即减少一切损失执行速度的可能性,这样便可用最快的速度填充整个数据库。例如,在程序设计上,Redisson通过Lua脚本的方式控制Redis,将每一页的Lua脚本交由Redis自身,而非使用Jedis连接的方式来解决,所以Redisson的性能一向优良。
我们分别通过INSERT INTO SELECT、存储过程和Loadfile三种方案为MySQL快速填充亿级数据。其中,INSERT INTO SELECT方案是MySQL提供的SQL语句,而SQL语句可直接在MySQL内执行,所以速度更快。存储过程方案可减少事务提交次数,并且可以增加包含逻辑结构的数据,以快速填充数据库。
Loadfile方案可将外置资源文件导入数据库,通过数据迁移的方式快速填充数据库。
为MySQL填充亿级数据实战
这里只准备了一台服务器作为MySQL服务器。该服务器内存1GB、硬盘20GB、CPU 1核、系统版本CentOS 6.5、MySQL版本5.1.73。
增加的测试数据的表结构如下所示:
在创建表之后,可以通过如下命令查看创建的表语句:
注意:该表仅用来测试,无其他特殊含义。
INSERT INTO SELECT方案
INSERT INTO SELECT语句可以先从一个表中复制数据,再把复制的数据插到一个已存在的表(目标表)中,并且目标表中已存在的行完全不受影响。从一个表中复制所有的列插到目标表中的命令如下所示:
也可以从一个表中只复制某些列插到目标表中:
1. INSERT INTO SELECT语句的优点和缺点
为数据库填充测试数据最快且最容易的方案是使用INSERT INTO SELECT语句。该方案不涉及任何I/O方面的消耗,最大的缺点是在创建数据时数据自由度不高。
注意,INSERT INTO SELECT语句只能为数据库填充数据,绝不能为数据库迁移数据。例如,需要将表A的数据迁移到表B中,虽然貌似可以使用INSERT INTO SELECT语句完成需求,但是INSERT INTO SELECT语句采用全表扫描的方式读取数据库资源,在默认的数据库隔离级别下,表B会被逐步行锁(扫一条锁一条),表A则会被表锁(全表加锁)。由于锁住的数据越来越多,进而导致数据库增删改大量失败,从而导致应用程序崩溃。
2. INSERT INTO SELECT语句的实现过程
(1)插入初始化数据:
初始化结果如图2-1所示。
(2)通过INSERT INTO SELECT语句创建数据:
在多次使用INSERT INTO SELECT语句之后,每次使用该语句都会使数据量翻倍。在硬盘与CPU足够的情况下,几秒即可填充亿级数据,结果如图2-2所示。
3. INSERT INTO SELECT语句可能出现的异常
当复制400万条数据到表中时已经出现了错误,如下所示:
这是由于缓冲区不够导致的,属于MySQL缓冲区异常。
此时需要在InnoDB buffer Pool中处理缓存,处理的缓存内容如下所示:
(1)数据缓存(InnoDB数据页面)。
(2)索引缓存(索引数据)。
(3)缓存数据(在内存中已修改但尚未写入磁盘的数据)。
(4)内部结构(如自适应哈希索引、行锁等)。
.……
因此,当MySQL大批量执行INSERT INTO SELECT语句时,要求InnoDBBuffer Pool要足够大,并且当InnoDB Buffer Pool较大时,还会提高INSERTINTO SELECT语句的执行效率。解决MySQL缓冲区异常的方式只有两种:
(1)在INSERT INTO SELECT语句中增加LIMIT限制性语句,保证每次增加的数据量缓冲区都可以承载。
(2)增加innodb_buffer_pool_size的值。
4. 增加innodb_buffer_pool_size的值的步骤
(1)使用下面的命令可以查看当前表使用了哪种数据库引擎:
结果如图2-3所示。
(2)使用下面的命令可以查看当前数据库引擎状态中的参数:
运行之后,截取部分参数,如表2-1所示。从表2-1中可以看出,innodb_buffer_pool_size的值为“8388608”,即为8MB。
(3)查看当前数据库引擎状态中的参数。
查找配置文件,在Linux系统中,配置文件是my.cnf;在Windows系统中,配置文件是my.ini。设置innodb_buffer_pool_size=64MB。更改之后,重 新 运 行 MySQL , 再 次 查 看 数 据 库 引 擎 状 态 中 的 参 数 可 以 发 现 ,innodb_buffer_pool_size的值已经修改了,如图2-4所示。
存储过程方案
存储过程(Stored Procedure)是数据库中可以完成某种特定功能的SQL语句集。用户可以通过指定存储过程的名称并给定参数(需要时)来调用并执行存储过程。我们可以把存储过程简单地理解为数据库在SQL语言层面的代
码封装与重用。MySQL是从5.0版本开始支持存储过程的。
1. 存储过程方案的优点和缺点
优点:
(1)存储过程可封装,并隐藏复杂的商业逻辑。
(2)存储过程可以回传值,并且可以接收参数。
(3)存储过程无法使用SELECT指令来运行,因为它是子程序,与查看表、数据表或用户定义函数等不同。
(4)存储过程可以用在数据检验上,强制执行商业逻辑等。
缺点:
(1)存储过程往往定制化于特定的数据库上,当切换到其他数据库时,因为支持的编程语言不同,需要重写原有的存储过程。
(2)存储过程的性能调校与编写通常受限于数据库。
2. 存储过程方案的实现过程
声明存储过程,如下所示:
注意:此处可以使用存储方案的随机数函数来创建数据。另外,如果要
增加事务,则不要过于频繁提交事务,否则会出现磁盘I/O异常。
调用存储过程如表2-2所示。
Loadfile方案
Loadfile方案相当于使用Java或Python等语言先创建CVS、txt等文件,再把数据存放在这些文件中,最后通过MySQL的Loadfile命令,把文件中的数据导入MySQL中。
1. Loadfile方案的优点和缺点
Loadfile方案与INSERT INTO SELECT方案和存储过程方案相比,自由度更高。但是从需要准备的文件来看,Loadfile方案整体所需要的时间比INSERT INTO SELECT方案和存储过程方案要多。
2. Loadfile方案的实现过程
(1)准备文件。
通过Java或Python等语言编写代码,输出相应的CVS文件或txt文件,文件内容如图2-5所示。
(2)把文件导入MySQL中。
使用如下命令把文件上传到服务端的/var/lib/mysql/目录下:
Navicat和SQLYog等工具也有上传文件的功能,但是数据库在连接这类工具时速度会慢很多。
第三方解决方案
1. DataFactory
DataFactory是一个大数据生成工具,可以按照数据的某些规律大批量地生成数据。该工具的特点是简单易用。
2. Datafaker
Datafaker是一个大批量测试数据和流测试数据的生成工具,是一个多数据源测试数据构造工具,可以模拟生成大部分常用数据类型的数据。
最终结果
当数据量为1亿1千万条左右时,如图2-6所示。另外,单表亿级数据量在硬盘中约占用5.4GB。因为表结构不同、数据量不同,所以不同的表对硬盘的占用情况也不同,此值只能作为参考。
通过SQL语句在无索引、单线程、无判断、无跨表,且单核CPU、1GB内存的情况下,获取当前表结构亿级表中的10条,所需时间约为0.061s。在优化SQL查询与表结构的过程中,可以把此值作为参考参数对SQL进行优化。
在实际工作中,可以用8核CPU、16GB内存、当前表结构和实际工作中的SQL并发数查询SQL,以得到最快响应时间,根据此响应时间长短进行优化。
要么修改表结构,修改SQL优化索引,要么修改代码减少查询次数,或者查看网络带宽是否到达上限。
若在实际工作中无法完成网络带宽受限的测试,那么就把代码中的响应时间与SQL响应时间进行对比。如果SQL响应速度更快,则优化代码与网络。
如果SQL响应速度较慢,则优化索引。如果无法优化索引,就修改表结构。
图2-7与图2-8分别展示了空表和亿级数据下,两种不同的磁盘使用(根据表结构与存储内容的不同,此数值仅作为参考)。
本文给大家讲解的内容是为MySQL填充亿级数据
- 下文给大家讲解的是MySQL基准测试:sysbench与mysqlslap
- 上一篇:用了缓存后,性能反而更慢了?
- 下一篇:勒索袭击新方式,提防注册机中注入的勒索病毒!
相关推荐
- C语言自学课程大纲(c语言入门自学资料)
-
一、自学C语言,很多人不知道应该如何学习,从哪儿学习,学习又分为几个阶段,总是学着学着就很迷茫???分享C语言的学习路线图,跟着路线图学吧,天天看。...
- 「linux」定时器方案:红黑树、最小堆和时间轮的原理
-
一、网络事件和时间事件对于服务端来说,驱动服务端逻辑的事件主要有两个,一个是网络事件,另一个是时间事件;...
- 程序员怎么会不知道 C10K 问题呢?
-
昨天的文章中提到了C10K问题,结果好些程序员跑过来问,啥是C10K,我写了这么多年程序,我怎么不知道呢?我说,那你听说过前腿儿猪肉吗?今天简单说说C10K的问题。关于这个问题,Ruby...
- 朝荐开源 - glib(朝廷百科)
-
glib是一套通用的实用程序库,它为C语言提供了许多有用的数据结构、工具函数和抽象层,旨在简化C语言的跨平台开发,并提高代码的可重用性和效率。glib是GTK+和GNOME桌面环...
- libevent总结(事件处理框架)(libevent libev)
-
libevent的事件处理框架是一个反应堆模型,而反应堆模型的核心就是io复用,拿epoll来说反应堆模型有两个核心数据结构,一个是epoll维护的内核事件表,一个是保存激活事件的事件队列当然,值得注...
- 日荐开源 - LibEvent(aldente官网网址)
-
libevent...
- 快递单号一键查询,高效追踪包裹物流,省时省力!
-
在繁忙的现代生活中,快递已成为我们日常生活中不可或缺的一部分。然而,面对众多的快递单号,如何快速、准确地查询包裹的物流信息成为了一个难题。现在,我们为您带来了一款快递单号一键查询工具,让您的物流追踪变...
- 导入不同快递公司下的单号批量查快递动态,一键解决物流查询难题
-
看着满屏快递单号陷入沉思?同事小王已经用《快递批量查询高手》一键导入多家快递,批量查询快递信息并统计了…而你还在中通、圆通、申通官网来回切换到鼠标冒烟?是时候亮出这个让快递公司接口“集体颤抖”的...
- 一键解锁快递查询高效能:批量查询快递,智能排序延误单号
-
当你的客服团队还在用5个浏览器轮番刷新物流页面时,隔壁仓库的王叔已经用快递批量查询高手把多个个滞留件变成会说话的预警红点!这篇教程将揭秘物流圈的「神器」,让「未更新快递」自动排队到你面前认罪。1.在软...
- 一站式快递单号查询平台,修改单号刷新快递信息的快递查询教程
-
一站式快递单号查询平台,支持导入单号查询时修改快递单号,高效刷新快递信息的快递查询教程随着电子商务的繁荣发展,快递业务量不断增长,无论是电商卖家还是普通消费者,对快递信息的查询和管理需求都日益增强。为...
- 高效快递单号查询,批量查询快递信息,多种查看方式满足你的需求
-
最近有很多朋友在问,如何查快递,怎么根据条件查看单号呢?不知道如何操作的宝贝们,下面请随小编一起来试试,希望能给大家带来帮助。需要哪些工具?安装一个快递批量查询高手快递单号若干怎么快速查询?步骤1:运...
- 物流查询达人必备!一键批量查询快递单号,根据发出时间筛选单号
-
嘿,各位快递查询达人们,是不是经常为海量的快递单号查询而头疼不已?想要一款能够在线批量查询快递动态,还能根据发出物流时间一键筛选所需快递单号信息的神器吗?来来来,让我给你们揭秘一款快递批量查询高手软件...
- 快递查询神器,多单号导入,筛选保存一键完成
-
当面对如山的快递单号,你是否曾感到手足无措?每一个单号都需要你逐一输入、查询,再逐个根据时间差进行筛选,这样的工作无疑是对耐心与精力的双重考验。但别担心,今天,我们将为你揭示一款物流行业的秘密武器——...
- 快递单号查询神器:一键复制粘贴,轻松批量追踪同公司快递
-
嘿,小伙伴们!还在为手动输入快递单号查询物流信息而烦恼吗?是不是觉得每次都要一个个输入单号,既费时又费力?别急,今天我要给大家介绍一款神奇的软件——快递批量查询高手!这款软件就像你的私人快递助手一样,...
- 快递单号查询入口自动批量查询快递动态并根据派件员字段排序单号
-
想象一下,面对堆积如山的快递单号,你不再需要一个个手动输入查询,而是轻轻一点,就能瞬间掌握所有快递的物流动态,甚至还能根据派件员智能排序,让管理变得井井有条。这不再是遥不可及的梦想,快递批量查询高手软...
你 发表评论:
欢迎- 一周热门
- 最近发表
- 标签列表
-
- wireshark怎么抓包 (75)
- qt sleep (64)
- cs1.6指令代码大全 (55)
- factory-method (60)
- sqlite3_bind_blob (52)
- hibernate update (63)
- c++ base64 (70)
- nc 命令 (52)
- wm_close (51)
- epollin (51)
- sqlca.sqlcode (57)
- lua ipairs (60)
- tv_usec (64)
- 命令行进入文件夹 (53)
- postgresql array (57)
- statfs函数 (57)
- .project文件 (54)
- lua require (56)
- for_each (67)
- c#工厂模式 (57)
- wxsqlite3 (66)
- dmesg -c (58)
- fopen参数 (53)
- tar -zxvf -c (55)
- 速递查询 (52)