码迷,mamicode.com
首页 > 数据库 > 详细

MySQL count(*)空表为何会很慢

时间:2015-08-27 11:27:45      阅读:203      评论:0      收藏:0      [点我收藏+]

标签:

Count(*)一个“空表”为什么会很慢呢?只有几十行数据为什么select xxx from table limit 1需要300msselect min(pk) fromtable也会慢?

见下例:

dba@localhost : test 18:14:32> show create table test_hmw\G
*************************** 1. row ***************************
    Table: test_hmw
Create Table: CREATE TABLE `test_hmw` (
 `mail` varchar(1024)DEFAULT NULL,
 `user_id` bigint(20)DEFAULT NULL,
 `id` int(10) unsigned NOTNULL AUTO_INCREMENT,
 PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3997636 DEFAULT CHARSET=utf8
1 row in set (0.00 sec)
dba@localhost : test 18:14:45> select count(*) from test_hmw;
+----------+
| count(*) |
+----------+
| 3813472 |
+----------+
1 row in set (0.69 sec)
dba@localhost : test 18:14:56> show status like ‘%last_query%‘;
+-----------------+---------------+
| Variable_name  |Value     |
+-----------------+---------------+
| Last_query_cost | 776677.599000 |
+-----------------+---------------+
1 row in set (0.00 sec)
dba@localhost : test 18:15:14> delete from test_hmw;
Query OK, 3813472 rows affected (15.11 sec)
dba@localhost : test 18:15:56> select count(*) fromtest_hmw; 
+----------+
| count(*) |
+----------+
|    0 |
+----------+
1 row in set (0.31 sec)
dba@localhost : test 18:15:59> show status like ‘%last_query%‘;
+-----------------+---------------+
| Variable_name  |Value     |
+-----------------+---------------+
| Last_query_cost | 757879.799000 |
+-----------------+---------------+
1 row in set (0.00 sec)


我们发现count一个空表的cost和删除前是一样的(时间不一样是因为缓存);其实在Oracle里也存在这个现象,对于select xx from table where rownum<xxx或者select count(*)之类的操作是从起始的block扫描到HMW;而在MySQL里不是HMWMySQL的多版本是直接存储在表里的,因此MySQL在删除了大量的数据,而purge thread回收前进行上面的操作就会扫描大量的“空”page因此也就有了这种现象;

既然知道原因在MySQL可以通过重整表的方式再来看看cost:

dba@localhost : test 18:16:01> optimize table test_hmw;
2 rows in set (1.85 sec)
dba@localhost : test 18:16:14> select count(*) fromtest_hmw; 
+----------+
| count(*) |
+----------+
|    0 |
+----------+
1 row in set (0.00 sec)
dba@localhost : test 18:16:16> show status like ‘%last_query%‘;
+-----------------+----------+
| Variable_name  |Value  |
+-----------------+----------+
| Last_query_cost | 1.199000 |
+-----------------+----------+
1 row in set (0.00 sec)


MySQL count(*)空表为何会很慢

标签:

原文地址:http://my.oschina.net/HeAlvin/blog/497707

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!