mysql导⼊千万数据库_如何向数据库集快速导⼊千万条数据⼀、数据导⼊的⽅式
向MySQL数据库导⼊数据,通常有两种办法,第⼀种是利⽤SOURCE命令,第⼆种是使⽤LOAD DATA命令。
SOURCE命令是通过执⾏SQL⽂件中的INSERT语句来实现数据的导⼊。正常情况下,如果我们向单节点的MySQL,⽤INSERT语句批量写⼊数据,在普通的PC机上,写⼊10万条数据,⼤概需要7~8分钟时间。按照这个速度推算,写⼊1千万条数据⼤概需要10个⼩时以上。如果在集条件下,这个速度会更慢。
MySQL的集分为PXC和Replication集。其中Replication集是异步传输的,它只保证事物在当前节点成功写⼊,数据是否能同步到其他节点,Replication集并不能给我们打包票。所以Replication集经常出现A节点写⼊数据,但是在B节点读取不到数据的情况。每年Apple秋季发布会之后,很多⼈会到Apple官⽹抢购iPhone⼿机,然⽽每年都有顾客会遇到付款之后,订单依旧是未⽀付的状态。这就是典型的Replication集的效果,数据出现了不⼀致。如果采⽤PXC集,因为数据是同步传输,所以我们在A节点写⼊数据,提交事务的时候,PXC必须保证所有MySQL节点都成功写⼊这条数据,才算事务提交成功,所以不会出现A节点写⼊数据,在B节点上读取不到数据的情况。因此PXC更加适合保存重要的数据,例如交易记录、学籍信息、考试成绩、⽤户信息等。另外,阿⾥巴巴在设计OceanBase数据库的时候也充分借鉴了PXC的原理。
再说回到数据导⼊,Replication只保证本节点写⼊,⽽PXC会保证所有节点写⼊。因此说,向Replication集写⼊数据会⽐PXC快,但都⽐单节点MySQL速度慢。
SOURCE命令执⾏的是INSERT语句,所以导⼊速度与我们执⾏INSERT语句没什么差别,如果数据量不多,还没什么问题,但是呢,如果从遗留数据库导出的数据特别多,上千万,甚⾄上亿。那么⽤SOURCE导⼊数据就会耗时很长。因此啊,我们要选择LOAD DATA导⼊。
为什么说LOAD DATA导⼊速度⽐SOURCE快很多倍呢,这是因为数据库执⾏SQL语句的时候会先校验语法,然后优化SQL,最后再执⾏。但是LOAD DATA导⼊的纯数据,于是就跳过了SQL的校验和优化,导⼊的速度也就⼤⼤提升了。
⼆、准备⼯作
下⾯我们通过程序来⽣成⼀个TXT⽂档,向⽂档中写⼊1千万条数据,再通过LOAD DATA导⼊数据。
这⾥我使⽤IBM的Xtend语⾔,来⽣成1千万条数。Xtend语⾔可以与Java语⾔完美兼容,除了语法更加简洁优雅之外,Xtend代码会被编译成Java代码。所以我们编写的代码最终会以Java程序来运⾏。这⼀点与Kotlin很像,但是Xtend语⾔的编译速度明显是Kotlin的4-6倍,开发效率真的是⾮常⾼。从我个⼈⾓度来说,⾮常推荐使⽤Xtend来改善Java啰嗦的语法。另外,⼤家可以在Eclipse的软件商店中到该插件,安装之后,你就能编写Xtend语⾔了。
import java.io.FileWriter
import java.io.BufferedWriter
class Test {
def static void main(String[] args) {
var writer=new FileWriter("D:/")
var buff=new BufferedWriter(writer)手机mysql安装配置教程
for(i:1..10000000){
buff.write(i+",测试数据
")
}
汇编语言入门代码buff.close
writer.close
}当图网个人简历模板下载
}
接下来我们把TXT⽂件上传到Linux系统,利⽤split把TXT⽂件切分成多个⽂件,这样就可以⽤Java多线程同时把多个TXT⽂件导⼊到数据库。
split -l 1000000 -
修改MySQL的配置⽂件
innodb_flush_log_at_trx_commit = 0
innodb_flush_method = O_DIRECT
innodb_buffer_pool_size = 200M
创建要导⼊数据的表
CREATE TABLE t_test(
id INT UNSIGNED PRIMARY KEY,
name VARCHAR(200) NOT NULL
);
三、编写Java程序,执⾏多线程导⼊
因为Java语⾔⾃带了线程池,所以我们先定义出来Runnable任务,然后交给多线程去执⾏导⼊TXT⽂档。
d.lib.annotations.Accessors
import java.io.File
import java.sql.DriverManager
class Task implements Runnable{
@Accessors
File file;
override run() {
var url="jdbc:mysql://192.168.99.131:8066/test"
var username="admin"
var password="Abc_123456"
var Connection(url,username,password)
var sql='''
load data local intfile '/home/data/«file.name»' ignore into table t_test
character set 'utf8'
fields terminated by ',' optionally enclosed by '"'
lines terminated by '
detect的名词' (id,name);
'''
var pst=con.prepareStatement(sql);
con.close
LoadData.updateNum();
}
}
sql.jdbc.Driver
import java.sql.DriverManager
import urrent.LinkedBlockingQueue
import urrent.ThreadPoolExecutor
import urrent.TimeUnit
import java.io.File
class LoadData {
var static int num=0;
var static int end=0;
var static pool=new ThreadPoolExecutor(1,5,60,TimeUnit.SECONDS,new LinkedBlockingQueue(200)) def static void main(String[] args) {
var folder=new File("/home/data")
var files=folder.listFiles
end=files.length //线程池结束条件
files.forEach[one|
var task=new Task();
task.file=one;
]
}
synchronized def static updateNum(){
currency是什么num++;
if(num==end){
pool.shutdown();
println("执⾏结束")
}
日期格式正则表达式java
}
}
在Linux系统上执⾏Java程序。我本地的主机配置是AMD 锐龙2700X,16GB内存和固态硬盘,1千万数据,只⽤了1分钟不到的时间就成功导⼊了。如果⽤SOURCE语句导⼊这些数据,需要10个⼩时以上。换做LOAD DATA指令,仅仅1分钟,速度提升了3万多倍,太让⼈吃惊了。
这是向单节点导⼊数据,如果向MySQL集导⼊数据,该怎么做呢?⾸先,如果是Replication集,因为节点间是异步传输,所以数据的导⼊速度最接近单节点MySQL,因此不⽤特别优化。如果是PXC集,因为节点之间是同步传输,所以写⼊速度较慢。不妨关闭其他PXC 节点,只保留⼀个MySQL节点,然后向该节点导⼊数据。这是为了避免向集导⼊数据的过程中,同步的速度赶不上写⼊的速度,导致PXC集限速,从⽽影响导⼊的速度。当我们在⼀个PXC节点导⼊成功之后,再陆续开启其他PXC节点,那么就不会产⽣⼤规模写⼊限速的问题了。
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论