Description:
Starting from MySQL 8.0.17, running 'select count(*)' on a big table is very slow.
== The query completes within 3-4 seconds in 5.7 and 8.0.16.
== Starting from 8.0.17, the query takes 1.5 to 2 minutes to complete
Explain plan in both the servers are same.
Profiling shows that the query is spending a huge time in "executing" state in 8.0.17+
How to repeat:
mysql> show create table test.dumm_table\G
*************************** 1. row ***************************
Table: dumm_table
Create Table: CREATE TABLE `dumm_table` (
`col1` bigint(20) NOT NULL AUTO_INCREMENT,
`col2` datetime DEFAULT NULL,
`col3` int(11) DEFAULT NULL,
`col4` varchar(256) CHARACTER SET utf8 COLLATE utf8_unicode_ci DEFAULT NULL,
`col5` int(4) DEFAULT NULL,
`col6` char(32) CHARACTER SET utf8 COLLATE utf8_unicode_ci DEFAULT NULL,
`col7` tinyint(4) DEFAULT NULL,
`col8` int(11) DEFAULT NULL,
`col9` tinyint(4) DEFAULT NULL,
`col10` tinyint(4) DEFAULT NULL,
`col11` int(11) DEFAULT NULL,
`col12` varchar(256) CHARACTER SET utf8 COLLATE utf8_unicode_ci DEFAULT NULL,
`col13` varchar(256) CHARACTER SET utf8 COLLATE utf8_unicode_ci DEFAULT NULL,
`col14` int(11) DEFAULT NULL,
`col15` tinyint(4) DEFAULT NULL,
`col16` tinyint(4) DEFAULT NULL,
`col17` tinyint(4) DEFAULT NULL,
`col18` tinyint(4) DEFAULT NULL,
`col19` tinyint(4) DEFAULT NULL,
`col20` varchar(128) CHARACTER SET utf8 COLLATE utf8_unicode_ci DEFAULT NULL,
`col21` char(32) CHARACTER SET utf8 COLLATE utf8_unicode_ci DEFAULT NULL,
`col22` varchar(128) CHARACTER SET utf8 COLLATE utf8_unicode_ci DEFAULT NULL,
`col23` char(32) CHARACTER SET utf8 COLLATE utf8_unicode_ci DEFAULT NULL,
`col24` varchar(128) CHARACTER SET utf8 COLLATE utf8_unicode_ci DEFAULT NULL,
`col25` char(32) CHARACTER SET utf8 COLLATE utf8_unicode_ci DEFAULT NULL,
`col26` decimal(3,1) DEFAULT NULL,
`col27` int(11) DEFAULT NULL,
`col28` int(11) DEFAULT NULL,
`col29` int(11) DEFAULT NULL,
`col30` varchar(1024) CHARACTER SET utf8 COLLATE utf8_unicode_ci DEFAULT NULL,
`col31` datetime DEFAULT NULL,
`col32` datetime DEFAULT NULL,
`col33` char(5) CHARACTER SET utf8 COLLATE utf8_unicode_ci DEFAULT NULL,
`col34` tinyint(4) DEFAULT NULL,
`col35` varchar(128) CHARACTER SET utf8 COLLATE utf8_unicode_ci DEFAULT NULL,
`col36` varchar(50) CHARACTER SET utf8 COLLATE utf8_unicode_ci DEFAULT NULL,
`col37` varchar(98) CHARACTER SET utf8 COLLATE utf8_unicode_ci DEFAULT NULL,
`col38` int(11) DEFAULT NULL,
`col39` int(11) DEFAULT NULL,
`col40` int(11) DEFAULT NULL,
`col41` int(11) DEFAULT NULL,
PRIMARY KEY (`col1`),
KEY `index_2` (`col2`),
KEY `index_3` (`col32`),
KEY `index_4` (`col6`),
KEY `index5` (`col3`,`col5`,`col11`),
KEY `index6` (`col6`,`col3`,`col2`,`col8`,`col5`),
KEY `index7` (`col6`,`col3`,`col2`,`col8`)
) ENGINE=InnoDB AUTO_INCREMENT=34078474 DEFAULT CHARSET=latin1
mysql> select @@version;
+-----------+
| @@version |
+-----------+
| 8.0.17 |
+-----------+
1 row in set (0.00 sec)
mysql> explain select count(*) from test.dumm_table;
+----+-------------+------------+------------+-------+---------------+---------+---------+------+----------+----------+-------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+------------+------------+-------+---------------+---------+---------+------+----------+----------+-------------+
| 1 | SIMPLE | dumm_table | NULL | index | NULL | index_2 | 6 | NULL | 32978504 | 100.00 | Using index |
+----+-------------+------------+------------+-------+---------------+---------+---------+------+----------+----------+-------------+
1 row in set, 1 warning (0.00 sec)
mysql> set profiling=1;
Query OK, 0 rows affected, 1 warning (0.00 sec)
mysql> select count(*) from test.dumm_table;
+----------+
| count(*) |
+----------+
| 33554432 |
+----------+
1 row in set (2 min 4.67 sec)
mysql> show profiles;
+----------+--------------+--------------------------------------+
| Query_ID | Duration | Query |
+----------+--------------+--------------------------------------+
| 1 | 124.66171775 | select count(*) from test.dumm_table |
+----------+--------------+--------------------------------------+
1 row in set, 1 warning (0.01 sec)
mysql> show profile for query 1;
+--------------------------------+------------+
| Status | Duration |
+--------------------------------+------------+
| starting | 0.000049 |
| Executing hook on transaction | 0.000002 |
| starting | 0.000006 |
| checking permissions | 0.000004 |
| Opening tables | 0.000025 |
| init | 0.000005 |
| System lock | 0.000006 |
| optimizing | 0.000004 |
| statistics | 0.000017 |
| preparing | 0.000012 |
| executing | 124.661489 |
| end | 0.000011 |
| query end | 0.000010 |
| waiting for handler commit | 0.000008 |
| closing tables | 0.000007 |
| freeing items | 0.000063 |
| cleaning up | 0.000002 |
+--------------------------------+------------+
17 rows in set, 1 warning (0.00 sec)
Able to reproduce even on 8.0.23 (latest version)
-----------------------------------
816> select @@version;
+-----------+
| @@version |
+-----------+
| 8.0.16 |
+-----------+
1 row in set (0.00 sec)
816> explain select count(*) from test.dumm_table;
+----+-------------+------------+------------+-------+---------------+---------+---------+------+----------+----------+-------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+------------+------------+-------+---------------+---------+---------+------+----------+----------+-------------+
| 1 | SIMPLE | dumm_table | NULL | index | NULL | index_2 | 6 | NULL | 32978504 | 100.00 | Using index |
+----+-------------+------------+------------+-------+---------------+---------+---------+------+----------+----------+-------------+
1 row in set, 1 warning (0.00 sec)
816> set profiling=1;
Query OK, 0 rows affected, 1 warning (0.00 sec)
816> select count(*) from test.dumm_table;
+----------+
| count(*) |
+----------+
| 33554432 |
+----------+
1 row in set (3.70 sec)
816> show profile for query 1;
+--------------------------------+----------+
| Status | Duration |
+--------------------------------+----------+
| starting | 0.000050 |
| Executing hook on transaction | 0.000002 |
| starting | 0.000006 |
| checking permissions | 0.000005 |
| Opening tables | 0.000023 |
| init | 0.000006 |
| System lock | 0.000006 |
| optimizing | 0.000004 |
| statistics | 0.000016 |
| preparing | 0.000018 |
| executing | 0.000002 |
| Sending data | 3.699323 |
| end | 0.000012 |
| query end | 0.000004 |
| waiting for handler commit | 0.000008 |
| closing tables | 0.000015 |
| freeing items | 0.000061 |
| cleaning up | 0.000003 |
+--------------------------------+----------+
18 rows in set, 1 warning (0.00 sec)
-----------------------------------
OBSERVATIONS MADE:
The DB server has 2vCPU and 8GB RAM
INNODB STATUS:
++ Row operations are very less in 8.0.17+
++ Row operations are high in 8.0.16
++ Buffer pool hit rate drops to a very low value as 5/1000 in 8.0.17+
++ Buffer pool hit rate is around 980/1000 in 8.0.16
COMPARING THE GLOBAL STATUS:
++ INNODB_ROWS_READ(delta) is equal to the number of rows in the table --> in 8.0.16
++ INNODB_ROWS_READ(delta) = 32 --> in 8.0.17
++ Handler_read_next(delta) is equal to the number of rows in the table --> in 8.0.16
++ Handler_read_next(delta) = 0 --> 8.0.17
++ Innodb_buffer_pool_pages_data and Innodb_buffer_pool_reads is 0 --> in 8.0.16
++ Innodb_buffer_pool_pages_data and Innodb_buffer_pool_reads is high for 8.0.17
Looks like some optimization in 8.0.17+ is leading to the issue.
Can you please confirm if this is expected?