mysql 与存储引擎的那些事

mysql 与存储引擎的那些事

一、介绍

mysql 有很多存储引擎,比较常用有InooDB,MyISAM,Memory,Merge,但用的比较多的是InnoDB,MyISAM。

存储引擎:MySQL中的数据用各种不同的技术存储在文件(或者内存)中。这些技术中的每一种技术都使用不同的存储机制、索引技巧、锁定水平并且最终提供广泛的不同的功能和能力。通过选择不同的技术,你能够获得额外的速度或者功能,从而改善你的应用的整体功能。这些不同的技术以及配套的相关功能在MySQL中被称作存储引擎(也称作表类型)。

二、程序问题

创建表时不指明存储引擎,系统就会使用默认存储引擎,默认存储引擎是InnoDB,如果要修改存储引擎,指令如下

alter table tablename engine=myisam;

将存储引擎更改为myisam

说说之前一些经历,往数据库中插入数据,数据量很大,大概有9900多万条数据,用的存储引擎是InnoDB。另外,表一共有5个字段,其中三个添加mul索引,还有一个是主键索引。在执行往数据库中插数据,速度特别慢。第一次使用的机器是普通的台式机,500Mb的数据插了将近4个小时,但总的数据有21G,这样的话,将这些数据插入到数据库花费的时间将达到一周,速度太慢了。而且还会出现 堆溢出的情况,然后就扩大缓冲池的大小buffer-pool-size = 256m。具体为` -Xms1024m -Xmx1500 -Xmn800m -XX:SurviorRation=8 ,这样就不会出现堆溢出的情况。中间又用到很多方法进行优化以提高速度,比如java程序中的往数据库插的代码,通过+号来连接字符串:

String sql = "insert into writesql(useragent,getREQ,date,time,url)" + "values('"+useragent+"', +getREQ+"','"+date+"','"+time+"','"+URL+"')"

这种代码在执行时,速度会比较慢。后来又换了一种方法,字符串连接使用StringBuilder#append来替代”+”真的会带来性能提升么

StringBuffer sql = new StringBuffer();
sql.append("insert into writesql(useragent,getREQ,time,url)")
    .append("values('")
    .append(useragent.replace("'", "\\'"))
    .append("', '")
    .append(getREQ.replace("'", "\\'"))
    .append("','")
    .append(time)
    .append("','")
    .append(URL.replace("'", "\\'"))
    .append("')");
```
`注`  “+”连接字符串会带来额外的内存消耗
append相对于会有一定的提升。另外,频繁往数据库中插入数据,sql语句可以用StringBuffer 代替String
再到后来,使用另外一种方法:

```shell
PreparedStatement insertItems = conn.prepareStatement("insert into writesql(mac,useragent,getREQ,time,url,router,path) values(?,?,?,?,?,?,?);");

insertItems.setString(1 , useragent);
insertItems.setString(2 , getREQ);
insertItems.setString(3 , time);
insertItems.setString(4 , URL);
insertItems.setString(5 , mac);
insertItems.setString(6 , router);
insertItems.setString(7 , path);

JDBC驱动里有个PreparedStatement的类,这个类可以大大的提高MySQL的速度和安全性,具体就是预编译相同类型的语句,这样每次提交请求的时候,就可以使用已经编译好的语句来查询或是更新数据库,虽然并不是什么情况都可以提高效率,但是使用他也不会降低效率;安全性方面就是防止了sql语句的漏洞。因为一次往数据库插入的数据量非常庞大,而PreparedStatement可以进行批处理。

选择PreparedStatement还是Statement取决于你要怎么使用它们. 对于只执行一次的SQL语句选择Statement是最好的。相反, 如果SQL语句被多次执行选用PreparedStatement是最好的。PreparedStatement的第一次执行消耗是很高的. 它的性能体现在后面的重复执行。而我这刚好满足重复执行insert语句。

statement 和PreparedStatement的区别

1、预防了sql注入的问题。因为在preparedStatement中把一些字符自动转义了。
2、Statement会使数据库频繁编译SQL,可能造成数据库缓冲区溢出。
PreparedStatement可对SQL进行预编译,从而提高数据库的执行效率。

前一段时间做的一些东西,总结一下吧。
使用系统,centos7,数据库用的是mariadb(centos7默认是mariadb),是可以兼容MySQL的。
将21G的数据导入到数据库中,用的存储引擎是InnoDB。往数据库插如数据很慢,而且插完之后,对已有的数据进行查询,查看日志文件,插入有9700多万条,数据量还是非常庞大的,已经添加过索引了。比如指令select count(*) from tablename ; 用的时间特别长,超过5分钟。有条件的查询也是一样特别慢,如select distinct url from tablename; 另外,中间又出现了一些问题,之前的数据又问题,又重新做了一遍。然后将这数据重新导入到数据库,就把就数据库的有问题的数据删除掉。但是我在执行指令delete from tablename; 用了一天的时间,数据仍然没有删除掉。后来在网上查了,删除数据delete速度是最慢的,另外还有两个删除数据的方法,drop和truncate,速度快慢drop>truncate>delete。也就说delete删除数据的速度是最慢的。delete删除数据的机制:

更换存储引擎,速度特别快。存储引擎为MyISAM。

三、实验

现在做一个测试:对比存储引擎,表结构等是否会对查询的速度有影响。

1、存储引擎是InnoDB

对一份文件,文件大概有6.7g,插入数据库条数大概有15856781条,存储引擎是InnoDB,将这些数据插入到数据所耗费的时间为9025秒。
表结构如下:这里写图片描述

这里写图片描述

通过查询语句select count(*) from writesql; 统计行数,所用时间为3.75秒。
通过已建的索引进行查询select distinct mac from writesql 查询没有重复的MAC地址,共有386行,所用的时间为0.12秒

2、存储引擎是MyISAM

对一份文件,文件大概有6.7g,插入数据库条数大概有15856781条,存储引擎是MyISAM,将这些数据插入到数据所耗费的时间为12229秒。
表的结构这里写图片描述

这里写图片描述

通过查询语句select count(*) from writesql; 统计行数,所用时间为0.00秒,瞬间出来。
通过已建的索引进行查询select distinct mac from writesql 查询没有重复的MAC地址,共有386行,所用的时间为0.02秒

可见,存储引擎不同会带来不同影响。存储引擎为InnoDB,将数据插入到数据库中的速度还是比存储引擎为myisam的快很多。但是存储引擎为InnoDB在查询数据时,会比较慢,也就是InnoDB不适合频繁读。

3、在原有的基础上在插入新的数据,速度会不会有变化呢?

3.1、存储引擎是InnoDB

对一份文件,文件大概有6.7g,插入数据库条数大概有36691238条,存储引擎是MyISAM,将这些数据插入到数据所耗费的时间为17151秒。
通过查询语句select count(*) from writesql; 统计行数,所用时间为0.00秒,瞬间出来。
通过已建的索引进行查询select distinct mac from writesql 查询没有重复的MAC地址,共有619行,所用的时间为0.15秒 。

3.2、存储引擎是MyISAM

对一份文件,文件大概有6.7g,插入数据库条数大概有36691238条,存储引擎是MyISAM,将这些数据插入到数据所耗费的时间为17151秒。
通过查询语句select count(*) from writesql; 统计行数,所用时间为0.00秒,瞬间出来。
通过已建的索引进行查询select distinct mac from writesql 查询没有重复的MAC地址,共有619行,所用的时间为0.15秒 。

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值