开发反馈数据库插入慢。我问及多少数据量时候。答复10万多数据,插入要很久。
其实任何一个主流数据库,区区十万数据根本不叫事。几秒就可以完成,甚至一秒写入10万也不奇怪。我之前公众号都写过。
请开发打开具体的SQL看看。SQL大致是这样的:
INSERT INTO T SELECT SUM(Y),XXX FROM T WHERE 一些条件 GROUP BY XXXXXX 。这里的T是同一个表,即,自己的一部分数据进行分组统计后再插入回到原本中。这里就是问题所在了,汇报的时候说写入数据是10几万。
但是实际上这个是分组以后十几万,并不代表实际数据只有十几万。
用例子来说明吧。
mysql> select * from t;
+------+----------+
| id | time |
+------+----------+
| 0 | 14:39:45 |
| 1 | 14:39:45 |
| 2 | 14:39:45 |
| 3 | 14:51:20 |
| 4 | 14:51:20 |
+------+----------+
5 rows in set (0.01 sec)
这个表只有5行数据。通过反复写入数据后
mysql> insert into t select * from t;
Query OK, 5 rows affected (0.01 sec)
Records: 5 Duplicates: 0 Warnings: 0
mysql> insert into t select * from t;
Query OK, 10 rows affected (0.00 sec)
Records: 10 Duplicates: 0 Warnings: 0
mysql> insert into t select * from t;
Query OK, 20 rows affected (0.00 sec)
Records: 20 Duplicates: 0 Warnings: 0
mysql> insert into t select * from t;
Query OK, 40 rows affected (0.01 sec)
Records: 40 Duplicates: 0 Warnings: 0
该表已经有80行数据了。
此时对这个表进行一下分组统计。
可以看出来分组是5行,但是实际扫描(读取)了80行。
mysql> select id,count(*) from t group by id;
+------+----------+
| id | count(*) |
+------+----------+
| 0 | 16 |
| 1 | 16 |
| 2 | 16 |
| 3 | 16 |
| 4 | 16 |
+------+----------+
5 rows in set (0.00 sec)
按照这样的数据写入,即使再写入数据:
mysql> insert into t select * from t;
Query OK, 80 rows affected (0.01 sec)
Records: 80 Duplicates: 0 Warnings: 0
mysql> select id,count(*) from t group by id;
+------+----------+
| id | count(*) |
+------+----------+
| 0 | 32 |
| 1 | 32 |
| 2 | 32 |
| 3 | 32 |
| 4 | 32 |
+------+----------+
5 rows in set (0.00 sec)
最终分组还是5行。
如果insert into t select id,count(*) from t group by id; 那么在开发角度来说最终是写入是5条。但是实际扫描(读取)了160行。
问题就是这样。
由于实际SQL写的复杂,都是多表连接的,背后select的都是乘以N倍的运算量。insert into 10万的数据,实际运算粗略估计在几千万级别的读取。难怪说执行的不快。
其实很多场景说insert 慢都是不对的。极有可能是insert into后面的select 慢。要么是读取数据量大,要么是全表扫描慢。
最后说一句,insert into table select 性别,count(*) from 中国人口,最终数据是2行,但是要知道这是扫描了14亿才出的2行啊。
这个时候要打开问题来分析一下,否则容易出现误会,觉得的是数据库什么参数不对,或者数据库不行,才十几万就不行了。其实正常使用的话:“这都不叫事!”