大家好,这里是java研究所。 很多粉丝问我:MySQL到底能支撑多少数据,是不是500万以上就不行了,查询就非常慢了? 这个问题问得好。到底行不行呢? 我觉得还是得通过实验来见证一下,mysql面对百万、千万、亿级别的数据时,查询到底行不行???
1亿数据查询速度
创建表test1
test1表,结构比较简单,2个字段,都有索引。
DROP TABLE IF EXISTS test1;
CREATE TABLE test1(
id int PRIMARY KEY COMMENT '编号' auto_increment,
order_num bigint comment '订单号'
)COMMENT '用户表';
/*order_num分别加索引*/
create index idx1 on test1(order_num);
插入1亿数据
@Test
public void test1() throws SQLException, ClassNotFoundException {
Class.forName("com.mysql.jdbc.Driver");
Connection connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/testdb?characterEncoding=UTF-8",
"root",
"密码");
StringBuilder sql = new StringBuilder("insert into test1(order_num) values ");
for (int i = 1; i <= 100000000; i++) {
sql.append(String.format("(%s),", i));
if (i % 10000 == 0) {
String s = sql.substring(0, sql.length() - 1);
sql = new StringBuilder("insert into test1(order_num) values ");
PreparedStatement ps = connection.prepareStatement(s);
ps.executeUpdate();
System.out.println(System.currentTimeMillis() + ":" + i);
}
}
}
无条件查询(耗时24秒)
耗时20多秒,如果给用户用,这个肯定是无法接受的。
mysql> select count(*) from test1;
+-----------+
| count(*) |
+-----------+
| 100000000 |
+-----------+
1 row in set (23.95 sec)
走索引查询(耗时1毫秒)
order_num 字段上面有索引,我们插入的时候,order_num 这个字段的值没有重复的。 用这个字段查询一下看看效果,耗时1毫秒,快不快,你们说???
select * from test1 where order_num = 9999999;
走索引,范围查询(耗时1毫秒)
select * from test1 where order_num >= 1000000 and order_num<= 1000010;
结论
- 不走索引,查询,这个基本上用不了,等着用户骂你吧。
- 走索引,毫秒级响应,1亿数据根本不是问题,即使是10亿数据,速度也差不多,大家可以试试。
再来个表,稍微复杂点
创建test2表 test2有3个字段,后面2个字段分别加了索引。
DROP TABLE IF EXISTS test2;
CREATE TABLE test2(
id int PRIMARY KEY COMMENT '编号' auto_increment,
user_id bigint comment '用户id',
order_num bigint comment '订单号'
)COMMENT '用户表';
/*user_id、order_num分别加索引*/
create index idx1 on test2(user_id);
create index idx2 on test2(order_num);
插入1亿数据
100万user_id,每个user_id下面关联100个order_num,共1亿数据
@Test
public void test2() throws SQLException, ClassNotFoundException {
Class.forName("com.mysql.jdbc.Driver");
Connection connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/testdb?characterEncoding=UTF-8",
"root",
"密码");
StringBuilder sql = new StringBuilder("insert into test2(user_id,order_num) values ");
int count = 0;
for (int user_id = 1; user_id <= 1000000; user_id++) {
for (int num = 1; num <= 100; num++) {
sql.append(String.format("(%s,%s),", user_id, count));
count++;
}
if (count % 10000 == 0) {
String s = sql.substring(0, sql.length() - 1);
sql = new StringBuilder("insert into test2(user_id,order_num) values ");
PreparedStatement ps = connection.prepareStatement(s);
ps.executeUpdate();
System.out.println(System.currentTimeMillis() + ":" + count);
}
}
}
无条件查询(耗时18秒)
mysql> select count(*) from test2;
+-----------+
| count(*) |
+-----------+
| 100000000 |
+-----------+
1 row in set (18.36 sec)
查询某个用户的数据(耗时1毫秒)
select * from test2 where user_id = 100000;
查询出来了100条数据,耗时也就1毫秒。
上面测试效果都是在我们笔记本上面的测试效果,如果放在线上去跑,数据会更好看!
总结一下
- mysql面对亿级别的数据到底行不行呢?看看上面的数据,不用我说了吧
- mysql数据量上去之后,比如千万,亿级别,如果不走索引,去查询,这个肯定是用不成的,用户是无法接受的。
- mysql数据量大了,千万,亿级别,查询的时候,带上条件,并且条件必须得走索引,那么速度是飞快的,毫秒级别的。
或许你还想看
- B站上有哪些值得推荐学习的视频?
- 经典面试题:重写equals方法时,为什么必须重写hashCode方法?
- 经典面试题:HashMap的默认容量为什么是16 ?
- 经典面试题:Arraylist和Linkedlist到底有什么区别???
- 经典面试题:NoClassDefFoundError 和 ClassNotFoundException 有什么区别?
- 经典面试题:Throwable、Exception、Error、RuntimeException到底有什么区别?
- 经典面试题:try、finally中都有return时,代码如何执行????
·END·
扫描二维码 | 关注我们