Bug #119480 Full table scans on primary keys, MySQL 8.0 performance degradation than MySQL 5.7.
Submitted: 1 Dec 9:38 Modified: 3 Dec 9:42
Reporter: haizhen xue Email Updates:
Status: Verified Impact on me:
None 
Category:MySQL Server: InnoDB storage engine Severity:S3 (Non-critical)
Version: OS:Any
Assigned to: CPU Architecture:Any

[1 Dec 9:38] haizhen xue
Description:
table:
CREATE TABLE `leads_discuss` (
     `id` int NOT NULL AUTO_INCREMENT COMMENT '??ID',
     `discuss_uuid` varchar(64) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '??UUID',
     `leads_id` int NOT NULL COMMENT '????ID',
     `discuss_type` int NOT NULL COMMENT '????',
     `discuss_classify` int DEFAULT NULL COMMENT '????',
     `start_time` datetime DEFAULT NULL COMMENT '????',
     `end_time` datetime DEFAULT NULL COMMENT '????',
     `next_time` datetime DEFAULT NULL COMMENT '????',
     `content` varchar(256) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '??',
     `is_test_drive` int DEFAULT NULL COMMENT '?????0-? 1-?',
     `address` varchar(64) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '??',
     `remarks` varchar(256) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '??',
     `customer_name` varchar(32) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '????',
     `customer_phone` varchar(64) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '?????',
     `create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '????',
     PRIMARY KEY (`id`),
     KEY `idx_leadsId` (`leads_id`) USING BTREE,
     KEY `idx_discussType` (`discuss_type`)
   ) ENGINE=InnoDB AUTO_INCREMENT=10464481 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='???????';

MySQL 8.0:
mysql> SELECT max(leads_id) FROM leads_discuss l FORCE INDEX (PRIMARY) WHERE l.id < 100000000;
+---------------+
| max(leads_id) |
+---------------+
|        100000 |
+---------------+
1 row in set (5.97 sec)

MySQL 5.7:
mysql> SELECT max(leads_id) FROM leads_discuss l FORCE INDEX (PRIMARY) WHERE l.id < 100000000;
+---------------+
| max(leads_id) |
+---------------+
|        100000 |
+---------------+
1 row in set (4.60 sec)

How to repeat:
1. create table:
CREATE TABLE `leads_discuss` (
     `id` int NOT NULL AUTO_INCREMENT COMMENT '??ID',
     `discuss_uuid` varchar(64) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '??UUID',
     `leads_id` int NOT NULL COMMENT '????ID',
     `discuss_type` int NOT NULL COMMENT '????',
     `discuss_classify` int DEFAULT NULL COMMENT '????',
     `start_time` datetime DEFAULT NULL COMMENT '????',
     `end_time` datetime DEFAULT NULL COMMENT '????',
     `next_time` datetime DEFAULT NULL COMMENT '????',
     `content` varchar(256) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '??',
     `is_test_drive` int DEFAULT NULL COMMENT '?????0-? 1-?',
     `address` varchar(64) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '??',
     `remarks` varchar(256) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '??',
     `customer_name` varchar(32) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '????',
     `customer_phone` varchar(64) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '?????',
     `create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '????',
     PRIMARY KEY (`id`),
     KEY `idx_leadsId` (`leads_id`) USING BTREE,
     KEY `idx_discussType` (`discuss_type`)
   ) ENGINE=InnoDB AUTO_INCREMENT=10464481 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='???????';

2. insert data:
DELIMITER $$
 CREATE PROCEDURE InsertLeadsDiscussDataOptimized()
 BEGIN
     DECLARE i INT DEFAULT 0;
     DECLARE batch_size INT DEFAULT 500;  -- 减小批次大小
     DECLARE total_batches INT DEFAULT CEIL(10459981 / 500);
     DECLARE current_batch INT DEFAULT 0;

     WHILE current_batch < total_batches DO
         START TRANSACTION;

         INSERT INTO leads_discuss (
             discuss_uuid, leads_id, discuss_type, discuss_classify,
             start_time, end_time, next_time, content, is_test_drive,
             address, remarks, customer_name, customer_phone, create_time
         )
         VALUES
         -- 动态生成500条数据
         (
             UUID(),
             FLOOR(1 + RAND() * 100000),
             FLOOR(1 + RAND() * 5),
             CASE WHEN RAND() > 0.3 THEN FLOOR(1 + RAND() * 3) ELSE NULL END,
             NOW() - INTERVAL FLOOR(RAND() * 365) DAY,
             CASE WHEN RAND() > 0.2 THEN NOW() - INTERVAL FLOOR(RAND() * 300) DAY ELSE NULL END,
             CASE WHEN RAND() > 0.3 THEN NOW() + INTERVAL FLOOR(RAND() * 30) DAY ELSE NULL END,
             CONCAT('讨论内容_', current_batch * batch_size + 1),
             CASE WHEN RAND() > 0.2 THEN FLOOR(RAND() * 2) ELSE NULL END,
             CONCAT('地址', FLOOR(1 + RAND() * 1000)),
             CASE WHEN RAND() > 0.4 THEN CONCAT('备注', current_batch * batch_size + 1) ELSE '' END,
             CONCAT('客户', FLOOR(1 + RAND() * 5000)),
             CONCAT('138', LPAD(FLOOR(RAND() * 100000000), 8, '0')),
             NOW() - INTERVAL FLOOR(RAND() * 365) DAY
         );

         -- 使用存储过程循环插入剩余499条
         SET @j = 1;
         WHILE @j < batch_size DO
             INSERT INTO leads_discuss (
                 discuss_uuid, leads_id, discuss_type, discuss_classify,
                 start_time, end_time, next_time, content, is_test_drive,
                 address, remarks, customer_name, customer_phone, create_time
             )
             SELECT
                 UUID(),
                 FLOOR(1 + RAND() * 100000),
                 FLOOR(1 + RAND() * 5),
                 CASE WHEN RAND() > 0.3 THEN FLOOR(1 + RAND() * 3) ELSE NULL END,
                 NOW() - INTERVAL FLOOR(RAND() * 365) DAY,
                 CASE WHEN RAND() > 0.2 THEN NOW() - INTERVAL FLOOR(RAND() * 300) DAY ELSE NULL END,
                 CASE WHEN RAND() > 0.3 THEN NOW() + INTERVAL FLOOR(RAND() * 30) DAY ELSE NULL END,
                 CONCAT('讨论内容_', current_batch * batch_size + @j + 1),
                 CASE WHEN RAND() > 0.2 THEN FLOOR(RAND() * 2) ELSE NULL END,
                 CONCAT('地址', FLOOR(1 + RAND() * 1000)),
                 CASE WHEN RAND() > 0.4 THEN CONCAT('备注', current_batch * batch_size + @j + 1) ELSE '' END,
                 CONCAT('客户', FLOOR(1 + RAND() * 5000)),
                 CONCAT('139', LPAD(FLOOR(RAND() * 100000000), 8, '0')),
                 NOW() - INTERVAL FLOOR(RAND() * 365) DAY;

             SET @j = @j + 1;
         END WHILE;

         COMMIT;

         SET current_batch = current_batch + 1;
         SET i = i + batch_size;

         -- 每1万条输出一次进度
         IF current_batch % 20 = 0 THEN
             SELECT CONCAT('进度: ', i, '/10459981 (', ROUND(i/10459981*100, 2), '%)') AS progress;
         END IF;
     END WHILE;

     SELECT CONCAT('数据插入完成! 总共插入: ', i, ' 条记录') AS completion_message;
 END$$
 DELIMITER ;
call InsertLeadsDiscussDataOptimized();
3. execute sql:
SELECT max(leads_id) FROM leads_discuss l FORCE INDEX (PRIMARY) WHERE l.id < 100000000;
[1 Dec 14:12] Øystein Grøvlen
Hi, and thank you for your report.

I see a smaller regression (9%) between 5.7 and 8.0, but there is no significant difference between 5.7 and 8.4 or 9.5:

mysql [localhost:5736] {msandbox} (bug119480) >  SELECT max(leads_id) FROM leads_discuss l FORCE INDEX (PRIMARY) WHERE l.id < 100000000;
+---------------+
| max(leads_id) |
+---------------+
|        100000 |
+---------------+
1 row in set (2.98 sec)

mysql [localhost:8044] {msandbox} (bug119480) > SELECT max(leads_id) FROM leads_discuss l FORCE INDEX (PRIMARY) WHERE l.id < 100000000;
+---------------+
| max(leads_id) |
+---------------+
|        100000 |
+---------------+
1 row in set (3.25 sec)

mysql [localhost:8407] {msandbox} (bug119480) > SELECT max(leads_id) FROM leads_discuss l FORCE INDEX (PRIMARY) WHERE l.id < 100000000;
+---------------+
| max(leads_id) |
+---------------+
|        100000 |
+---------------+
1 row in set (3.00 sec)

mysql [localhost:9500] {msandbox} (bug119480) >  SELECT max(leads_id) FROM leads_discuss l FORCE INDEX (PRIMARY) WHERE l.id < 100000000;
+---------------+
| max(leads_id) |
+---------------+
|        100000 |
+---------------+
1 row in set (3.008 sec)

In my case, all data was in memory.  What is your setting for innodb_buffer_pool_size?  It would also be useful to see the result of the following query for both versions:

select * from mysql.innodb_index_stats where table_name = 'leads_discuss';
[2 Dec 6:42] haizhen xue
between 5.7 and 8.0, it has a regression (12.4%) when all data was in memory.
There is a question: why is the value of Innodb_buffer_pool_read_requests much lower in MySQL 8.0 compared to MySQL 5.7?
Before and after executing SQL statements, the increase in the value of Innodb_buffer_pool_read_requests in MySQL 8.0 is much smaller compared to MySQL 5.7.

8.0.44:
mysql> select * from mysql.innodb_index_stats where table_name = 'leads_discuss';
+---------------+---------------+-----------------+---------------------+--------------+------------+-------------+-----------------------------------+
| database_name | table_name    | index_name      | last_update         | stat_name    | stat_value | sample_size | stat_description                  |
+---------------+---------------+-----------------+---------------------+--------------+------------+-------------+-----------------------------------+
| test          | leads_discuss | PRIMARY         | 2025-12-02 10:59:23 | n_diff_pfx01 |    9252244 |          20 | id                                |
| test          | leads_discuss | PRIMARY         | 2025-12-02 10:59:23 | n_leaf_pages |      98063 |        NULL | Number of leaf pages in the index |
| test          | leads_discuss | PRIMARY         | 2025-12-02 10:59:23 | size         |      98176 |        NULL | Number of pages in the index      |
| test          | leads_discuss | idx_discussType | 2025-12-02 10:59:23 | n_diff_pfx01 |          4 |           6 | discuss_type                      |
| test          | leads_discuss | idx_discussType | 2025-12-02 10:59:23 | n_diff_pfx02 |    9566356 |          20 | discuss_type,id                   |
| test          | leads_discuss | idx_discussType | 2025-12-02 10:59:23 | n_leaf_pages |       7966 |        NULL | Number of leaf pages in the index |
| test          | leads_discuss | idx_discussType | 2025-12-02 10:59:23 | size         |       8175 |        NULL | Number of pages in the index      |
| test          | leads_discuss | idx_leadsId     | 2025-12-02 10:59:23 | n_diff_pfx01 |     103845 |          20 | leads_id                          |
| test          | leads_discuss | idx_leadsId     | 2025-12-02 10:59:23 | n_diff_pfx02 |    8975237 |          20 | leads_id,id                       |
| test          | leads_discuss | idx_leadsId     | 2025-12-02 10:59:23 | n_leaf_pages |      11752 |        NULL | Number of leaf pages in the index |
| test          | leads_discuss | idx_leadsId     | 2025-12-02 10:59:23 | size         |      13489 |        NULL | Number of pages in the index      |
+---------------+---------------+-----------------+---------------------+--------------+------------+-------------+-----------------------------------+
11 rows in set (0.00 sec)

mysql> SHOW STATUS LIKE 'Innodb_buffer_pool_read%';
+---------------------------------------+-----------+
| Variable_name                         | Value     |
+---------------------------------------+-----------+
| Innodb_buffer_pool_read_ahead_rnd     | 0         |
| Innodb_buffer_pool_read_ahead         | 1264917   |
| Innodb_buffer_pool_read_ahead_evicted | 3798      |
| Innodb_buffer_pool_read_requests      | 104072442 |
| Innodb_buffer_pool_reads              | 73861     |
+---------------------------------------+-----------+
5 rows in set (0.01 sec)

mysql> SELECT max(leads_id) FROM leads_discuss l FORCE INDEX (PRIMARY) WHERE l.id < 100000000;
+---------------+
| max(leads_id) |
+---------------+
|        100000 |
+---------------+
1 row in set (3.70 sec)

mysql> SHOW STATUS LIKE 'Innodb_buffer_pool_read%';
+---------------------------------------+-----------+
| Variable_name                         | Value     |
+---------------------------------------+-----------+
| Innodb_buffer_pool_read_ahead_rnd     | 0         |
| Innodb_buffer_pool_read_ahead         | 1264917   |
| Innodb_buffer_pool_read_ahead_evicted | 3798      |
| Innodb_buffer_pool_read_requests      | 104201092 |
| Innodb_buffer_pool_reads              | 73861     |
+---------------------------------------+-----------+
5 rows in set (0.00 sec)

5.7.44:
mysql> select * from mysql.innodb_index_stats where table_name = 'leads_discuss';
+---------------+---------------+-----------------+---------------------+--------------+------------+-------------+-----------------------------------+
| database_name | table_name    | index_name      | last_update         | stat_name    | stat_value | sample_size | stat_description                  |
+---------------+---------------+-----------------+---------------------+--------------+------------+-------------+-----------------------------------+
| test          | leads_discuss | PRIMARY         | 2025-12-02 14:24:46 | n_diff_pfx01 |    9964773 |          20 | id                                |
| test          | leads_discuss | PRIMARY         | 2025-12-02 14:24:46 | n_leaf_pages |     103155 |        NULL | Number of leaf pages in the index |
| test          | leads_discuss | PRIMARY         | 2025-12-02 14:24:46 | size         |     103360 |        NULL | Number of pages in the index      |
| test          | leads_discuss | idx_discussType | 2025-12-02 14:24:46 | n_diff_pfx01 |          4 |           6 | discuss_type                      |
| test          | leads_discuss | idx_discussType | 2025-12-02 14:24:46 | n_diff_pfx02 |   10062452 |          20 | discuss_type,id                   |
| test          | leads_discuss | idx_discussType | 2025-12-02 14:24:46 | n_leaf_pages |       8377 |        NULL | Number of leaf pages in the index |
| test          | leads_discuss | idx_discussType | 2025-12-02 14:24:46 | size         |       8558 |        NULL | Number of pages in the index      |
| test          | leads_discuss | idx_leadsId     | 2025-12-02 14:24:46 | n_diff_pfx01 |     104706 |          20 | leads_id                          |
| test          | leads_discuss | idx_leadsId     | 2025-12-02 14:24:46 | n_diff_pfx02 |    9265788 |          20 | leads_id,id                       |
| test          | leads_discuss | idx_leadsId     | 2025-12-02 14:24:46 | n_leaf_pages |      13290 |        NULL | Number of leaf pages in the index |
| test          | leads_discuss | idx_leadsId     | 2025-12-02 14:24:46 | size         |      15217 |        NULL | Number of pages in the index      |
+---------------+---------------+-----------------+---------------------+--------------+------------+-------------+-----------------------------------+
11 rows in set (0.00 sec)

mysql> SHOW STATUS LIKE 'Innodb_buffer_pool_read%';
+---------------------------------------+-----------+
| Variable_name                         | Value     |
+---------------------------------------+-----------+
| Innodb_buffer_pool_read_ahead_rnd     | 0         |
| Innodb_buffer_pool_read_ahead         | 1066953   |
| Innodb_buffer_pool_read_ahead_evicted | 0         |
| Innodb_buffer_pool_read_requests      | 126336696 |
| Innodb_buffer_pool_reads              | 52346     |
+---------------------------------------+-----------+
5 rows in set (0.00 sec)
mysql> SELECT max(leads_id) FROM leads_discuss l FORCE INDEX (PRIMARY) WHERE l.id < 100000000;
+---------------+
| max(leads_id) |
+---------------+
|        100000 |
+---------------+
1 row in set (3.29 sec)

mysql> SHOW STATUS LIKE 'Innodb_buffer_pool_read%';
+---------------------------------------+-----------+
| Variable_name                         | Value     |
+---------------------------------------+-----------+
| Innodb_buffer_pool_read_ahead_rnd     | 0         |
| Innodb_buffer_pool_read_ahead         | 1066953   |
| Innodb_buffer_pool_read_ahead_evicted | 0         |
| Innodb_buffer_pool_read_requests      | 127606222 |
| Innodb_buffer_pool_reads              | 52346     |
+---------------------------------------+-----------+
5 rows in set (0.00 sec)
[3 Dec 9:42] Øystein Grøvlen
If I set innodb_buffer_pool_size to 1GB (previously it was 128 GB), 8.4 and 9.5 are even slower than 8.0:

mysql [localhost:5736] {msandbox} (bug119480) > SELECT max(leads_id) FROM leads_discuss l FORCE INDEX (PRIMARY) WHERE l.id < 100000000;
+---------------+
| max(leads_id) |
+---------------+
|        100000 |
+---------------+
1 row in set (4.16 sec)

mysql [localhost:8044] {msandbox} (bug119480) > SELECT max(leads_id) FROM leads_discuss l FORCE INDEX (PRIMARY) WHERE l.id < 100000000;
+---------------+
| max(leads_id) |
+---------------+
|        100000 |
+---------------+
1 row in set (4.58 sec)

mysql [localhost:8407] {msandbox} (bug119480) > SELECT max(leads_id) FROM leads_discuss l FORCE INDEX (PRIMARY) WHERE l.id < 100000000;
+---------------+
| max(leads_id) |
+---------------+
|        100000 |
+---------------+
1 row in set (5.28 sec)

mysql [localhost:9500] {msandbox} (bug119480) > SELECT max(leads_id) FROM leads_discuss l FORCE INDEX (PRIMARY) WHERE l.id < 100000000;
+---------------+
| max(leads_id) |
+---------------+
|        100000 |
+---------------+
1 row in set (5.214 sec)