MySQL从5.7.28升级到8.0.27后,使用PREPARE语句的IN查询执行缓慢



这是我正在使用的技术堆栈,Java 11, JOOQ 3.12.1和MYSQL 8.0.28(从5.7.28升级),连接池(30)和引擎InnoDB。

下面是我在MySQL 5.7.28中使用JOOQ在15秒内成功执行的示例查询。IN查询大约需要60k个id。现在MYSQL 8.0.28的查询大约需要92秒。

select `id`, `name`, `description` from `ex_table` where `id` in (?,?,?,?,?,....);

就信息而言,我已经使用了mariadb和mysql连接器,所以我可以得出结论,连接器没有问题。

[编辑]

show create table ex_table;
+------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Table      | Create Table                                                                                                                                                                                                                                                                                                                                                              |
+------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| ex_table | CREATE TABLE `ex_table` (
`id` int unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(255) NOT NULL,
`description` varchar(1000) DEFAULT NULL,
`stack_id` mediumint unsigned NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `unq_node` (`name`,`stack_id`),
KEY `idx_stack` (`stack_id`)
) ENGINE=InnoDB AUTO_INCREMENT=72279 DEFAULT CHARSET=utf8mb3 |
+------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.02 sec)

SHOW TABLE STATUS WHERE name LIKE 'ex_table';
+------------+--------+---------+------------+-------+----------------+-------------+-----------------+--------------+-----------+----------------+---------------------+-------------+------------+-----------------+----------+----------------+---------+
| Name       | Engine | Version | Row_format | Rows  | Avg_row_length | Data_length | Max_data_length | Index_length | Data_free | Auto_increment | Create_time         | Update_time | Check_time | Collation       | Checksum | Create_options | Comment |
+------------+--------+---------+------------+-------+----------------+-------------+-----------------+--------------+-----------+----------------+---------------------+-------------+------------+-----------------+----------+----------------+---------+
| ex_table | InnoDB |      10 | Dynamic    | 60272 |             43 |     2637824 |               0 |      5275648 |   4194304 |          72279 | 2022-06-30 07:10:14 | NULL        | NULL       | utf8_general_ci |     NULL |                |         |
+------------+--------+---------+------------+-------+----------------+-------------+-----------------+--------------+-----------+----------------+---------------------+-------------+------------+-----------------+----------+----------------+---------+
1 row in set (0.02 sec)

explain select `id`, `name`, `description`, `stack_id` from `ex_table` where `id` in (1,2,3,4,5,6,7,8,9,10);
+----+-------------+------------+------------+-------+---------------+---------+---------+------+------+----------+-------------+
| id | select_type | table      | partitions | type  | possible_keys | key     | key_len | ref  | rows | filtered | Extra       |
+----+-------------+------------+------------+-------+---------------+---------+---------+------+------+----------+-------------+
|  1 | SIMPLE      | ex_table | NULL       | range | PRIMARY       | PRIMARY | 4       | NULL |   10 |   100.00 | Using where |
+----+-------------+------------+------------+-------+---------------+---------+---------+------+------+----------+-------------+
1 row in set, 1 warning (0.01 sec)


Running Full Query with Explain:
+----+-------------+------------+------------+------+---------------+------+---------+------+-------+----------+-------------+
| id | select_type | table      | partitions | type | possible_keys | key  | key_len | ref  | rows  | filtered | Extra       |
+----+-------------+------------+------------+------+---------------+------+---------+------+-------+----------+-------------+
|  1 | SIMPLE      | ex_table | NULL       | ALL  | PRIMARY       | NULL | NULL    | NULL | 60272 |    50.00 | Using where |
+----+-------------+------------+------------+------+---------------+------+---------+------+-------+----------+-------------+
1 row in set, 2 warnings (0.51 sec)

SLOW QUERY LOG

# Time: 2022-07-18T14:38:02.110872-00:00
# User@Host: user[host] @ localhost [127.0.0.1]
# Schema: dbname  Last_errno: 0  Killed: 0
# Query_time: 33.762935  Lock_time: 0.075141  Rows_sent: 60052  Rows_examined: 60052  Rows_affected: 0  Bytes_sent: 1619164
use dbname;
SET timestamp=1658155048;
select `dbname`.`ex_table`.`id`, `dbname`.`ex_table`.`name`, `dbname`.`ex_table`.`description`, `dbname`.`ex_table`.`stack_id` from `dbname`.`ex_table` where `dbname`.`ex_table`.`id` in (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, ... );

[编辑2]优化器跟踪

{
"steps": [
{
"statement_parameters": [
"LONGLONG",
"LONGLONG",
"LONGLONG",
"LONGLONG",
"LONGLONG",
"LONGLONG",
"LONGLONG",
……,
…..,
]
},
{
"join_optimization": {
"select#": 1,
"steps": [
{
"condition_processing": {
"condition": "WHERE",
"original_condition": "(`ex_table`.`id` in (1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101, …))”,
"steps": [
{
"transformation": "equality_propagation",
"resulting_condition": "(`ex_table `.`id` in (1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,…))”
},
{
"transformation": "trivial_condition_removal",
"resulting_condition": "(`ex_table `.`id` in (1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,…))”,
"final_table_condition   ": "(`ex_table`.`id` in (1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,..))”
}
]
},
{
"refine_plan": [
{
"table": "`ex_table`”
}
]
}
]
}
},
{
"join_execution": {
"select#": 1,
"steps": [
]
}
}
]
}
Explain format=json SELECT ...
{
"query_block": {
"select_id": 1,
"cost_info": {
"query_cost": "6047.05"
},
"table": {
"table_name": “ex_table”,
"access_type": "ALL",
"possible_keys": [
"PRIMARY"
],
"rows_examined_per_scan": 60068,
"rows_produced_per_join": 30034,
"filtered": "50.00",
"cost_info": {
"read_cost": "3043.65",
"eval_cost": "3003.40",
"prefix_cost": "6047.05",
"data_read_per_join": "108M"
},
"used_columns": [
"id",
"name",
"description",
“stack”_id
],
"attached_condition": "(`db`.`ex_table`.`id` in (1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,….))”
}
}
}

我以前遇到过这种情况,主要是因为两个版本的查询优化器之间的差异,当然这与innodb的几个参数有关。

相关内容

  • 没有找到相关文章

最新更新