一、问题描述
最近遇到一个问题,我们先来模拟一下如下,我分别在5.7.22、8.0.22、8.0.40测试了结果一致。 - 初始化数据
scss
drop table mytest123;
create table mytest123(id int auto_increment primary key,a int ,b int ,c int , key(a,b,c));
insert into mytest123(a,b,c) values(1,6,15);
insert into mytest123(a,b,c) values(1,6,16);
insert into mytest123(a,b,c) values(1,6,17);
insert into mytest123(a,b,c) values(1,7,18);
insert into mytest123(a,b,c) values(1,7,19);
insert into mytest123(a,b,c) values(1,7,20);
insert into mytest123(a,b,c) values(2,8,21);
insert into mytest123(a,b,c) values(2,8,22);
insert into mytest123(a,b,c) values(2,8,23);
insert into mytest123(a,b,c) values(2,9,24);
insert into mytest123(a,b,c) values(2,9,25);
insert into mytest123(a,b,c) values(2,9,26);
insert into mytest123(a,b,c) values(2,10,27);
insert into mytest123(a,b,c) values(2,10,28);
insert into mytest123(a,b,c) values(2,10,29);
alter table mytest123 add ic int;
- 设置和查询
sql
set optimizer_switch='index_condition_pushdown=off';
set long_query_time=0;
mysql> select * from mytest123 where a=2 AND b>7 AND b<10 AND C=21;
+----+------+------+------+------+
| id | a | b | c | ic |
+----+------+------+------+------+
| 19 | 2 | 8 | 21 | NULL |
+----+------+------+------+------+
1 row in set (0.01 sec)
mysql> select * from mytest123 where a=2 AND b>=8 AND b<=9 AND C=21;
+----+------+------+------+------+
| id | a | b | c | ic |
+----+------+------+------+------+
| 19 | 2 | 8 | 21 | NULL |
+----+------+------+------+------+
1 row in set (0.00 sec)
- 查看慢查询
ini
# Query_time: 0.005866 Lock_time: 0.001287 Rows_sent: 1 Rows_examined: 6 Rows_affected: 0
# Bytes_sent: 284
SET timestamp=1758008055;
select * from mytest123 where a=2 AND b>7 AND b<10 AND C=21;
# Time: 2025-09-16T15:34:21.844519+08:00
# User@Host: root[root] @ localhost [] Id: 5
# Schema: test Last_errno: 0 Killed: 0
# Query_time: 0.004336 Lock_time: 0.001124 Rows_sent: 1 Rows_examined: 3 Rows_affected: 0
# Bytes_sent: 284
SET timestamp=1758008061;
select * from mytest123 where a=2 AND b>=8 AND b<=9 AND C=21;
虽然2个语句返回的数据一样,但是我们注意这里的Rows_examined,两个语句的Rows_examined分别为6和3,那么通常代表了2个语句返回给mysql层的数据量不一样,为什么会这样呢?我们分析一下。
二、执行计划分析
首先我们将条件分为, - 条件A:a=2 AND b>7 AND b<10 AND C=21 - 条件B:a=2 AND b>=8 AND b<=9 AND C=21
我们先看看常规的执行计划,
sql
mysql> desc select * from mytest123 where a=2 AND b>7 AND b<10 AND C=21;
+----+-------------+-----------+------------+-------+---------------+------+---------+------+------+----------+-------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+-----------+------------+-------+---------------+------+---------+------+------+----------+-------------+
| 1 | SIMPLE | mytest123 | NULL | range | a | a | 10 | NULL | 6 | 10.00 | Using where |
+----+-------------+-----------+------------+-------+---------------+------+---------+------+------+----------+-------------+
1 row in set, 1 warning (0.01 sec)
mysql> desc select * from mytest123 where a=2 AND b>=8 AND b<=9 AND C=21;
+----+-------------+-----------+------------+-------+---------------+------+---------+------+------+----------+-------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+-----------+------------+-------+---------------+------+---------+------+------+----------+-------------+
| 1 | SIMPLE | mytest123 | NULL | range | a | a | 15 | NULL | 3 | 10.00 | Using where |
+----+-------------+-----------+------------+-------+---------------+------+---------+------+------+----------+-------------+
1 row in set, 1 warning (0.00 sec)
我们发现这里key_len分别为10和15,因为字段全部为int类型4字节,每个字段增加null_bit字节,所以一个字段的长度为5字节,因为10和15分别代表了使用的字段不同,同时key_len在范围扫描中有2个作用, - 代表了定位数据的开始位置start key的长度 - 代表了扫描结束的位置end key的长度
注意这里end key 和filter不是一个概念,filter的条件会在扫描一条数据后给到filter条件过滤得到实际的结果,但是扫描数据会继续执行,filter这不会减少扫描量。而end key会作为范围扫描的结束位置,不再扫描数据,会显著的减少扫描量。后面我们在分析end key在范围扫描中的作用,这个例子刚好也和这个有关。 接下来分别讨论如下2个语句条件中key_len的不同, - A:a=2 AND b>7 AND b<10 AND C=21 :这个条件key_len为10代表定位数据使用字段a和b,同时结束条件end key也是a和b,C=21这个条件并不作为扫描结束的条件,那么这个条件只能作为filter条件了,也就是如下,
scss
...
(1,7,20)
(2,8,21) <--- 定位
(2,8,22)
(2,8,23)
(2,9,24)
(2,9,25)
(2,9,26)
(2,10,27) --->判断结束扫描
...
这里我们看到这里就是扫描了7条数据,但是最后一条并没有返回给mysql层,因此为6行。然后通过filter 过滤条件C=21
- B:a=2 AND b>=8 AND b<=9 AND C=21:这个条件key_len为15代表定位数据使用字段a、b和c,同时结束条件end key也是a、b和c,C=21这个条件作为扫描结束的条件。但是从上图可以看到如果C=21作为了结束条件为什么还需要扫描3条数据呢,而不是一条数据呢,因为(2,8,22)这条数据22是显然不满足C=21的条件的,后面我们再分析为什么会这样。
接下来我们看看8.0.40的新执行计划如下,
markdown
mysql> desc format=tree select * from mytest123 where a=2 AND b>7 AND b<10 AND C=21 \G
*************************** 1. row ***************************
EXPLAIN: -> Filter: ((mytest123.c = 21) and (mytest123.a = 2) and (mytest123.b > 7) and (mytest123.b < 10)) (cost=2.96 rows=0.6)
-> Index range scan on mytest123 using a over (a = 2 AND 7 < b < 10) (cost=2.96 rows=6)
1 row in set (0.00 sec)
mysql> desc format=tree select * from mytest123 where a=2 AND b>=8 AND b<=9 AND C=21 \G
*************************** 1. row ***************************
EXPLAIN: -> Filter: ((mytest123.c = 21) and (mytest123.a = 2) and (mytest123.b >= 8) and (mytest123.b <= 9)) (cost=1.61 rows=0.3)
-> Index range scan on mytest123 using a over (a = 2 AND 8 <= b <= 9 AND c = 21) (cost=1.61 rows=3)
1 row in set (0.01 sec)
这里可以看到如下, - 条件A:Index range scan on mytest123 using a over (a = 2 AND 7 < b < 10) - 条件B:Index range scan on mytest123 using a over (a = 2 AND 8 <= b <= 9 AND c = 21)
也是我们这里说的问题。
三、关于条件B的end key 判定
首先start key 会定位到如下位置
scss
a b c
...
(1,7,20)
(2,8,21) <--- 定位
(2,8,22)
(2,8,23)
(2,9,24)
(2,9,25)
(2,9,26)
(2,10,27)
...
然后顺序扫描数据,当然这里可能会使用record buffer一次进行多行数据的扫描,但是每行索引数据都必须过函数key_cmp进行判断,判断是否范围扫描应该结束了,这个函数会对每行数据库关于索引字段的数据和条件中的范围进行比对,但是它比对的时候,并不会各个字段都比对,比如当前条件B的条件为a=2 AND b>=8 AND b<=9 AND C=21,那么首先比对记录中为(2,8,21),比对a字段符合条件a=2,然后比对b字段的8是否和b<=9中的9相同,如果不相同是否小于,如果小于就直接返回-1,代表在范围中,而不会再次比对C=21这个条件了,如下,
rust
469 if ((cmp = key_part->field->key_cmp(key, key_part->length)) < 0)
(gdb)
470 return -res;
(gdb) x/4bx key
0x7fff2417a2ee: 0x09 0x00 0x00 0x00
(gdb) x/4bx key_part->field->ptr
0x7fff24b7eb06: 0x08 0x00 0x00 0x00
(gdb) p -res
$20 = -1
key为范围条件b<=9中的9
key_part->field->ptr为b实际的值
当比对到(2,9,24)这行记录的时候发现a=2和b<=9中的9相同 这两个条件都相同,才会比较C=21这个条件,如下,
rust
(gdb) x/4bx key_part->field->ptr
0x7fff24b7eb1f: 0x18 0x00 0x00 0x00
(gdb) x/4bx key
0x7fff2417a2f3: 0x15 0x00 0x00 0x00
key为范围条件c=21中的21(0X15)
key_part->field->ptr为c实际的值24(0x18)
因此这里返回1,代表已经大于了范围,应该结束扫描,最终通过filter C=21 得到正确的结果,因此扫描的记录为,
scss
a b c
...
(1,7,20)
(2,8,21) <--- 定位
(2,8,22)
(2,8,23)
(2,9,24) ---> 判断扫描结束
(2,9,25)
(2,9,26)
(2,10,27)
...
也就是扫描4行,返回给mysql层3行记录。
其次,ICP 是否和可以避免这种情况呢?前面我们测试的时候都关闭了ICP,index_condition_pushdown=off,如果开启过后是否可以降低返回给mysql层行数,案例说这里如果把C=21这个条件下推到innodb层,就可以达到目的,下面我们看看打开后的慢查询,
ini
# Time: 2025-09-16T06:15:03.681681-04:00
# User@Host: root[root] @ localhost [] Id: 7
# Query_time: 0.001744 Lock_time: 0.000017 Rows_sent: 1 Rows_examined: 1
SET timestamp=1758017703;
select * from mytest123 where a=2 AND b>7 AND b<10 AND C=21;
# Time: 2025-09-16T06:15:07.186251-04:00
# User@Host: root[root] @ localhost [] Id: 7
# Query_time: 0.001729 Lock_time: 0.000014 Rows_sent: 1 Rows_examined: 1
SET timestamp=1758017707;
select * from mytest123 where a=2 AND b>=8 AND b<=9 AND C=21;
确实这里我们看到两个语句扫描的行数都是1,从执行计划看下推了整个条件,因此在innodb层就阻挡了返回过多的行给mysql层。
最后:使用区分度更高的字段作为联合索引的前缀
这个案例中我们发现字段a的区分度太低,如果使用字段c作为索引的前缀就可以避免这种问题,这时这个索引的值就是如下,
scss
c b a
...
(20,7,1)
(21,8,2) <- 定位
(22,8,2) --> 判断扫描结束
(23,8,2)
(24,9,2)
(25,9,2)
(26,9,2)
(27,10,2)
...
不管条件是A还是条件B,都是定位到记录(21,8,2) 上,然后扫描下一条记录,当进行范围比较的时候发现22已经大于了C=21的条件,因此扫描直接就结束了,慢查询中条件是A和条件B都只记录一行数据,如下。
sql
mysql> set optimizer_switch='index_condition_pushdown=off';
Query OK, 0 rows affected (0.00 sec)
mysql> alter table mytest123 drop index a ;
alter table mytest123 add key(c,b,a);
Query OK, 0 rows affected (17.17 sec)
Records: 0 Duplicates: 0 Warnings: 0
mysql> alter table mytest123 add key(c,b,a);
Query OK, 0 rows affected (0.18 sec)
Records: 0 Duplicates: 0 Warnings: 0
mysql> select * from mytest123 where a=2 AND b>7 AND b<10 AND C=21;
+----+------+------+------+------+
| id | a | b | c | ic |
+----+------+------+------+------+
| 19 | 2 | 8 | 21 | NULL |
+----+------+------+------+------+
1 row in set (0.00 sec)
mysql> select * from mytest123 where a=2 AND b>=8 AND b<=9 AND C=21;
+----+------+------+------+------+
| id | a | b | c | ic |
+----+------+------+------+------+
| 19 | 2 | 8 | 21 | NULL |
+----+------+------+------+------+
1 row in set (0.00 sec)
慢查询如下,注意观察 Rows_examined: 1,这也是一个使用区分度更高字段作为联合索引前缀的一个有利例子,
ini
# Time: 2025-09-16T23:26:21.259023+08:00
# User@Host: root[root] @ localhost [] Id: 7
# Query_time: 2820.754121 Lock_time: 0.000307 Rows_sent: 1 Rows_examined: 1
SET timestamp=1758033560;
select * from mytest123 where a=2 AND b>=8 AND b<=9 AND C=21;
# Time: 2025-09-16T23:31:04.054857+08:00
# User@Host: root[root] @ localhost [] Id: 7
# Query_time: 280.268767 Lock_time: 0.000493 Rows_sent: 1 Rows_examined: 1
SET timestamp=1758036383;
select * from mytest123 where a=2 AND b>=8 AND b<=9 AND C=21;
其他
shell
--------------------------------------------------------------
drop table mytest123;
create table mytest123(id int auto_increment primary key,a int ,b int ,c int , key(a,b,c));
insert into mytest123(a,b,c) values(1,6,15);
insert into mytest123(a,b,c) values(1,6,16);
insert into mytest123(a,b,c) values(1,6,17);
insert into mytest123(a,b,c) values(1,7,18);
insert into mytest123(a,b,c) values(1,7,19);
insert into mytest123(a,b,c) values(1,7,20);
insert into mytest123(a,b,c) values(2,8,21);
insert into mytest123(a,b,c) values(2,8,22);
insert into mytest123(a,b,c) values(2,8,23);
insert into mytest123(a,b,c) values(2,9,24);
insert into mytest123(a,b,c) values(2,9,25);
insert into mytest123(a,b,c) values(2,9,26);
insert into mytest123(a,b,c) values(2,10,27);
insert into mytest123(a,b,c) values(2,10,28);
insert into mytest123(a,b,c) values(2,10,29);
alter table mytest123 add ic int;
alter table mytest123 drop index a ;
alter table mytest123 add key(c,b,a);
select * from mytest123 where a=2 AND b>7 AND b<10 AND C=21; Rows_examined: 6
select * from mytest123 where a=2 AND b>=8 AND b<=9 AND C=21; Rows_examined: 3
# Time: 2025-09-14T22:47:43.049996+08:00
# User@Host: root[root] @ localhost [] Id: 7
# Query_time: 0.001638 Lock_time: 0.000469 Rows_sent: 1 Rows_examined: 3
SET timestamp=1757861263;
select * from mytest123 where a=2 AND b>=8 AND b<=9 AND C=21;
# Time: 2025-09-14T22:47:48.441253+08:00
# User@Host: root[root] @ localhost [] Id: 7
# Query_time: 0.001896 Lock_time: 0.000307 Rows_sent: 1 Rows_examined: 6
SET timestamp=1757861268;
select * from mytest123 where a=2 AND b>7 AND b<10 AND C=21;
(gdb) bt
#0 btr_cur_search_to_nth_level (index=0x7fff180e8dd0, level=0, tuple=0x7fff18bcd138, mode=PAGE_CUR_G, latch_mode=1, cursor=0x7fff18bcced8, has_search_latch=0, file=0x690aa80 "/newdata/mysql-8.0.23/storage/innobase/row/row0sel.cc", line=4926, mtr=0x7fffcc3a6ec0) at /newdata/mysql-8.0.23/storage/innobase/btr/btr0cur.cc:641
#1 0x0000000004a62b38 in btr_pcur_t::open_no_init (this=0x7fff18bcced8, index=0x7fff180e8dd0, tuple=0x7fff18bcd138, mode=PAGE_CUR_G, latch_mode=1, has_search_latch=0, mtr=0x7fffcc3a6ec0, file=0x690aa80 "/newdata/mysql-8.0.23/storage/innobase/row/row0sel.cc", line=4926) at /newdata/mysql-8.0.23/storage/innobase/include/btr0pcur.h:720
#2 0x0000000004ba6738 in row_search_mvcc (buf=0x7fff18b58a18 "\377", mode=PAGE_CUR_G, prebuilt=0x7fff18bccc50, match_mode=0, direction=0) at /newdata/mysql-8.0.23/storage/innobase/row/row0sel.cc:4926
#3 0x0000000004936086 in ha_innobase::index_read (this=0x7fff18b73958, buf=0x7fff18b58a18 "\377", key_ptr=0x7fff18b809f8 "", key_len=10, find_flag=HA_READ_AFTER_KEY) at /newdata/mysql-8.0.23/storage/innobase/handler/ha_innodb.cc:9800
#4 0x00000000035c5ffe in handler::index_read_map (this=0x7fff18b73958, buf=0x7fff18b58a18 "\377", key=0x7fff18b809f8 "", keypart_map=3, find_flag=HA_READ_AFTER_KEY) at /newdata/mysql-8.0.23/sql/handler.h:4996
#5 0x00000000035b406e in handler::ha_index_read_map (this=0x7fff18b73958, buf=0x7fff18b58a18 "\377", key=0x7fff18b809f8 "", keypart_map=3, find_flag=HA_READ_AFTER_KEY) at /newdata/mysql-8.0.23/sql/handler.cc:3244
#6 0x00000000035bede1 in handler::read_range_first (this=0x7fff18b73958, start_key=0x7fff18b73a40, end_key=0x7fff18b73a60, eq_range_arg=false, sorted=false) at /newdata/mysql-8.0.23/sql/handler.cc:7219
#7 0x00000000049376a7 in ha_innobase::read_range_first (this=0x7fff18b73958, start_key=0x7fff18b73a40, end_key=0x7fff18b73a60, eq_range_arg=false, sorted=false) at /newdata/mysql-8.0.23/storage/innobase/handler/ha_innodb.cc:10272
#8 0x00000000035bcc68 in handler::multi_range_read_next (this=0x7fff18b73958, range_info=0x7fffcc3a8190) at /newdata/mysql-8.0.23/sql/handler.cc:6375
#9 0x00000000035bdbbe in DsMrr_impl::dsmrr_next (this=0x7fff18b74f68, range_info=0x7fffcc3a8190) at /newdata/mysql-8.0.23/sql/handler.cc:6723
#10 0x0000000004951008 in ha_innobase::multi_range_read_next (this=0x7fff18b73958, range_info=0x7fffcc3a8190) at /newdata/mysql-8.0.23/storage/innobase/handler/ha_innodb.cc:22710
#11 0x00000000035bc976 in handler::ha_multi_range_read_next (this=0x7fff18b73958, range_info=0x7fffcc3a8190) at /newdata/mysql-8.0.23/sql/handler.cc:6313
#12 0x00000000030f5e06 in QUICK_RANGE_SELECT::get_next (this=0x7fff18089070) at /newdata/mysql-8.0.23/sql/opt_range.cc:10987
#13 0x00000000031379e9 in IndexRangeScanIterator::Read (this=0x7fff18b42a90) at /newdata/mysql-8.0.23/sql/records.cc:307
#14 0x0000000003910ac9 in FilterIterator::Read (this=0x7fff18b42ac8) at /newdata/mysql-8.0.23/sql/composite_iterators.cc:83
#15 0x00000000033638af in SELECT_LEX_UNIT::ExecuteIteratorQuery (this=0x7fff18b86f58, thd=0x7fff180062f0) at /newdata/mysql-8.0.23/sql/sql_union.cc:1228
#16 0x0000000003363bdf in SELECT_LEX_UNIT::execute (this=0x7fff18b86f58, thd=0x7fff180062f0) at /newdata/mysql-8.0.23/sql/sql_union.cc:1281
#17 0x00000000032bbf26 in Sql_cmd_dml::execute_inner (this=0x7fff18bca610, thd=0x7fff180062f0) at /newdata/mysql-8.0.23/sql/sql_select.cc:827
#18 0x00000000032bb495 in Sql_cmd_dml::execute (this=0x7fff18bca610, thd=0x7fff180062f0) at /newdata/mysql-8.0.23/sql/sql_select.cc:612
#19 0x000000000324475e in mysql_execute_command (thd=0x7fff180062f0, first_level=true) at /newdata/mysql-8.0.23/sql/sql_parse.cc:4407
#20 0x00000000032465fb in dispatch_sql_command (thd=0x7fff180062f0, parser_state=0x7fffcc3a9aa0) at /newdata/mysql-8.0.23/sql/sql_parse.cc:4988
#21 0x000000000323cfa4 in dispatch_command (thd=0x7fff180062f0, com_data=0x7fffcc3aab40, command=COM_QUERY) at /newdata/mysql-8.0.23/sql/sql_parse.cc:1836
#22 0x000000000323b513 in do_command (thd=0x7fff180062f0) at /newdata/mysql-8.0.23/sql/sql_parse.cc:1320
#23 0x000000000340dfb1 in handle_connection (arg=0x8a61350) at /newdata/mysql-8.0.23/sql/conn_handler/connection_handler_per_thread.cc:301
#24 0x000000000500dc16 in pfs_spawn_thread (arg=0xa68dc50) at /newdata/mysql-8.0.23/storage/perfschema/pfs.cc:2900
#25 0x00007ffff7bc6ea5 in start_thread () from /lib64/libpthread.so.0
#26 0x00007ffff61418dd in clone () from /lib64/libc.so.6
handler::ha_index_read_map
->handler::index_read_map
struct key_range {
const uchar *key;
uint length;
key_part_map keypart_map;
enum ha_rkey_function flag;
};
typedef ulong key_part_map;
{key = 0x7fff2011c098 "", length = 10, keypart_map = 3, flag = HA_READ_AFTER_KEY}
ha_rkey_function的取值
enum ha_rkey_function {
HA_READ_KEY_EXACT, /* Find first record else error */
HA_READ_KEY_OR_NEXT, /* Record or next record */
HA_READ_KEY_OR_PREV, /* Record or previous */
HA_READ_AFTER_KEY, /* Find next rec. after key-record */
HA_READ_BEFORE_KEY, /* Find next rec. before key-record */
HA_READ_PREFIX, /* Key which as same prefix */
HA_READ_PREFIX_LAST, /* Last key with the same prefix */
HA_READ_PREFIX_LAST_OR_PREV, /* Last or prev key with the same prefix */
HA_READ_MBR_CONTAIN, /* Minimum Bounding Rectangle contains */
HA_READ_MBR_INTERSECT, /* Minimum Bounding Rectangle intersect */
HA_READ_MBR_WITHIN, /* Minimum Bounding Rectangle within */
HA_READ_MBR_DISJOINT, /* Minimum Bounding Rectangle disjoint */
HA_READ_MBR_EQUAL, /* Minimum Bounding Rectangle equal */
HA_READ_INVALID = -1 /* Invalid enumeration value, always last. */
};
handler::multi_range_read_next
完成多个范围的读取,对于一个范围来讲
->handler::read_range_first
首先定位第一条数据,使用key的数量和len
->handler::read_range_next
访问吓一条数据,并且判断end范围 是否已经满足
但是innodb不是这里判定
handler::ha_set_record_buffer
handler::compare_key_in_buffer
key_part[0]
key_part[1]
key_part[2]
(gdb) bt
#0 key_cmp (key_part=0x7fff18cf81b8, key=0x7fff1804dbf8 "", key_length=15) at /newdata/mysql-8.0.23/sql/key.cc:450
#1 0x00000000035bf592 in handler::compare_key_in_buffer (this=0x7fff180a7c28, buf=0x7fff18b7d188 "\220\024") at /newdata/mysql-8.0.23/sql/handler.cc:7441
#2 0x0000000004ba3fde in row_search_end_range_check (mysql_rec=0x7fff18b7d188 "\220\024", rec=0x7fff9b828220 "\200", prebuilt=0x7fff1807fea0, clust_templ_for_sec=true, offsets=0x0, record_buffer=0x7fff180a9c80) at /newdata/mysql-8.0.23/storage/innobase/row/row0sel.cc:3946
#3 0x0000000004ba8b4c in row_search_mvcc (buf=0x7fff18cf38a8 "\361\023", mode=PAGE_CUR_GE, prebuilt=0x7fff1807fea0, match_mode=0, direction=0) at /newdata/mysql-8.0.23/storage/innobase/row/row0sel.cc:5701
#4 0x0000000004936086 in ha_innobase::index_read (this=0x7fff180a7c28, buf=0x7fff18cf38a8 "\361\023", key_ptr=0x7fff1804dbe8 "", key_len=15, find_flag=HA_READ_KEY_OR_NEXT) at /newdata/mysql-8.0.23/storage/innobase/handler/ha_innodb.cc:9800
#5 0x00000000035c5ffe in handler::index_read_map (this=0x7fff180a7c28, buf=0x7fff18cf38a8 "\361\023", key=0x7fff1804dbe8 "", keypart_map=7, find_flag=HA_READ_KEY_OR_NEXT) at /newdata/mysql-8.0.23/sql/handler.h:4996
#6 0x00000000035b406e in handler::ha_index_read_map (this=0x7fff180a7c28, buf=0x7fff18cf38a8 "\361\023", key=0x7fff1804dbe8 "", keypart_map=7, find_flag=HA_READ_KEY_OR_NEXT) at /newdata/mysql-8.0.23/sql/handler.cc:3244
#7 0x00000000035bede1 in handler::read_range_first (this=0x7fff180a7c28, start_key=0x7fff180a7d10, end_key=0x7fff180a7d30, eq_range_arg=false, sorted=false) at /newdata/mysql-8.0.23/sql/handler.cc:7219
#8 0x00000000049376a7 in ha_innobase::read_range_first (this=0x7fff180a7c28, start_key=0x7fff180a7d10, end_key=0x7fff180a7d30, eq_range_arg=false, sorted=false) at /newdata/mysql-8.0.23/storage/innobase/handler/ha_innodb.cc:10272
#9 0x00000000035bcc68 in handler::multi_range_read_next (this=0x7fff180a7c28, range_info=0x7fffcc3a8190) at /newdata/mysql-8.0.23/sql/handler.cc:6375
#10 0x00000000035bdbbe in DsMrr_impl::dsmrr_next (this=0x7fff180a9238, range_info=0x7fffcc3a8190) at /newdata/mysql-8.0.23/sql/handler.cc:6723
#11 0x0000000004951008 in ha_innobase::multi_range_read_next (this=0x7fff180a7c28, range_info=0x7fffcc3a8190) at /newdata/mysql-8.0.23/storage/innobase/handler/ha_innodb.cc:22710
#12 0x00000000035bc976 in handler::ha_multi_range_read_next (this=0x7fff180a7c28, range_info=0x7fffcc3a8190) at /newdata/mysql-8.0.23/sql/handler.cc:6313
#13 0x00000000030f5e06 in QUICK_RANGE_SELECT::get_next (this=0x7fff1804c180) at /newdata/mysql-8.0.23/sql/opt_range.cc:10987
#14 0x00000000031379e9 in IndexRangeScanIterator::Read (this=0x7fff18b7d108) at /newdata/mysql-8.0.23/sql/records.cc:307
#15 0x0000000003910ac9 in FilterIterator::Read (this=0x7fff18b7d140) at /newdata/mysql-8.0.23/sql/composite_iterators.cc:83
#16 0x00000000033638af in SELECT_LEX_UNIT::ExecuteIteratorQuery (this=0x7fff18b75218, thd=0x7fff180062f0) at /newdata/mysql-8.0.23/sql/sql_union.cc:1228
#17 0x0000000003363bdf in SELECT_LEX_UNIT::execute (this=0x7fff18b75218, thd=0x7fff180062f0) at /newdata/mysql-8.0.23/sql/sql_union.cc:1281
#18 0x00000000032bbf26 in Sql_cmd_dml::execute_inner (this=0x7fff18b78928, thd=0x7fff180062f0) at /newdata/mysql-8.0.23/sql/sql_select.cc:827
#19 0x00000000032bb495 in Sql_cmd_dml::execute (this=0x7fff18b78928, thd=0x7fff180062f0) at /newdata/mysql-8.0.23/sql/sql_select.cc:612
#20 0x000000000324475e in mysql_execute_command (thd=0x7fff180062f0, first_level=true) at /newdata/mysql-8.0.23/sql/sql_parse.cc:4407
#21 0x00000000032465fb in dispatch_sql_command (thd=0x7fff180062f0, parser_state=0x7fffcc3a9aa0) at /newdata/mysql-8.0.23/sql/sql_parse.cc:4988
#22 0x000000000323cfa4 in dispatch_command (thd=0x7fff180062f0, com_data=0x7fffcc3aab40, command=COM_QUERY) at /newdata/mysql-8.0.23/sql/sql_parse.cc:1836
#23 0x000000000323b513 in do_command (thd=0x7fff180062f0) at /newdata/mysql-8.0.23/sql/sql_parse.cc:1320
#24 0x000000000340dfb1 in handle_connection (arg=0x88b9150) at /newdata/mysql-8.0.23/sql/conn_handler/connection_handler_per_thread.cc:301
#25 0x000000000500dc16 in pfs_spawn_thread (arg=0xa448340) at /newdata/mysql-8.0.23/storage/perfschema/pfs.cc:2900
#26 0x00007ffff7bc6ea5 in start_thread () from /lib64/libpthread.so.0
#27 0x00007ffff61418dd in clone () from /lib64/libc.so.6