我的编程空间,编程开发者的网络收藏夹
学习永远不晚

Mysql优化器对in list的处理

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

Mysql优化器对in list的处理

select * from table where id in (....)
这样的查询,是走范围索引还是走等值索引?
select * from table where key_part1 in (....) and key_part2='XX';
这样的查询,第二部分还走不走索引?

测试目的,想知道,MYSQL对IN LIST是如何选择执行计划的;在单字段索引和复合索引中;

[@more@]


mysql 5.1.40
os:rhel 5.4
engine=innodb
innodb_file_per_table


# 先来创建测试环境:
create table index_test ( id int auto_increment , col1 int ,col2 varchar(200) ,content varchar(500),primary key (id) ,key col1 (col1) ) engine=innodb default charset=latin1;
# repeat insert operation 12 times

insert into index_test (col1,col2) select @rownum:=@rownum+1,column_name from information_schema.COLUMNS c , (select @rownum:=0 ) id limit 500 ;


# 测试1:先测对主键的IN操作;

# 测试用例:
reset query cache; --清空QUERY_CAHCE
show status like 'Innodb_buffer_pool_read_requests' ; --用来查询逻辑读
select * from index_test where id in (2,10,1000,2000,9000);
show status like 'Innodb_buffer_pool_read_requests' ; --与前面的结果相减,就得到SQL执行所带来的逻辑读 ;
为了逻辑读的准确性, 对同一个SQL你应该多跑几次,以去掉物理读 ;


root@127.0.0.1 : test 16:02:16> explain select * from index_test where id in (2,10,1000,2000);
+----+-------------+------------+-------+---------------+---------+---------+------+------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+------------+-------+---------------+---------+---------+------+------+-------------+
| 1 | SIMPLE | index_test | range | PRIMARY | PRIMARY | 4 | NULL | 4 | Using where |
+----+-------------+------------+-------+---------------+---------+---------+------+------+-------------+
1 row in set (0.00 sec)

# 从执行计划看,走的是范围条件;但我们看看实际情况 :
# 注意,为了减少篇幅,我把各个查询的结果给删减了。


select * from index_test where id in (2,10);
RESULTs: 2 rows
LIO  : 4

select * from index_test where id in (2,1000);
RESULTs: 2 rows
LIO  : 4

select * from index_test where id in (2,10,100);
RESULTs: 3 rows
LIO  : 6

select * from index_test where id in (2,10,1000,2000);
RESULTs: 4 rows
LIO  : 8

select * from index_test where id in (2,10,1000,2000,9000);
RESULTs: 5 rows
LIO  : 10

### 在这里看到,逻辑读根据IN LIST里KEY的数量成线性增加,而没有根据KEY值的大小变化,所以我们判断,对主键的IN操作,其实都转成了OR操作。


# 测试2:对非主键的IN操作;
# 测试用例:
reset query cache;
show status like 'Innodb_buffer_pool_read_requests' ;
select * from index_test where col1 in (100,500,300,400);
show status like 'Innodb_buffer_pool_read_requests' ;


root@127.0.0.1 : test 16:06:33> explain select * from index_test where col1 in (100,200);
+----+-------------+------------+-------+---------------+------+---------+------+------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+------------+-------+---------------+------+---------+------+------+-------------+
| 1 | SIMPLE | index_test | range | col1 | col1 | 5 | NULL | 24 | Using where |
+----+-------------+------------+-------+---------------+------+---------+------+------+-------------+
1 row in set (0.00 sec)

select * from index_test where col1 in (100,101);
RESULTs: 24 rows
LIO : 86

select * from index_test where col1 in (100,500);
RESULTs: 24 rows
LIO : 86

select * from index_test where col1 in (100,500,300);
RESULTs: 36 rows
LIO : 139

select * from index_test where col1 in (100,500,300,400);
RESULTs: 48 rows
LIO : 172

分析: 这个结果与测试1的结果是一样的;


# 测试3:对复合索引的前列IN操作;
alter table index_test drop index col1 ,add index col1col2(col1,col2) ;
update index_test set content=concat(col2,col3,col1) ;

主要是测一下,索引的第一个字段用IN后,优化器还会不会使用第二个字段来进行索引搜索;

root@127.0.0.1 : test 18:41:38> explain select content from index_test where col1 in (100,500,300,400) and col2='aaaa';
+----+-------------+------------+-------+---------------+----------+---------+------+------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+------------+-------+---------------+----------+---------+------+------+-------------+
| 1 | SIMPLE | index_test | range | col1col2 | col1col2 | 208 | NULL | 4 | Using where |
+----+-------------+------------+-------+---------------+----------+---------+------+------+-------------+
1 row in set (0.00 sec)



select count(*) from index_test where col1 in (100,500,300,400) and col2='aaaa';
RESULTs: 0 rows
LIO : 24

select content from index_test where col1 in (100,500,300,400) and col2='aaaa';
RESULTs: 0 rows
LIO : 24

分析:
#我们发现,两个查询的逻辑读是一样,其实这已经表明优化器用上了索引的第二个字段,在索引搜索部分就完成了对COL2的过滤;

总结:MYSQL优化器对in list是转成“or” 的“多个等值”查询来处理的;并没有转成范围查询 ;

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

Mysql优化器对in list的处理

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

CentOS Firefox怎样针对特定的处理器进行优化

本篇文章为大家展示了CentOS Firefox怎样针对特定的处理器进行优化,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。将 CentOS Firefox 针对特定的处理器进行优化之后便是 Cent
2023-06-16

MySQL红黑树对索引碎片化的处理

MySQL索引使用的是B+树,而不是红黑树。B+树更适合磁盘等辅助存储设备中的情况,能够有效减少磁盘IO次数,提高查询效率。以下是MySQL索引碎片化的处理方式:索引碎片化的原因插入、更新和删除操作:这些操作可能导致索引块的分裂或移动,从
MySQL红黑树对索引碎片化的处理
2024-10-07

索引在Oracle中处理大对象数据的优化

在Oracle中处理大对象数据时,可以通过以下方式来优化索引的性能:使用功能索引:功能索引可以根据大对象数据的特定函数或操作进行索引,以提高检索速度。例如,可以使用SUBSTR函数来创建一个功能索引,以部分匹配大对象数据。使用合适的索引类型
索引在Oracle中处理大对象数据的优化
2024-08-15

聚合函数对大数据处理的优化方案

在处理大数据时,使用聚合函数可以有效地减少数据量,提高查询性能。以下是一些优化方案:分布式计算:将大数据分布在多台机器上进行并行计算,以提高处理速度。数据分片:将大数据按照不同的维度进行分片存储,并使用合适的分片策略进行查询,以减少数据量。
聚合函数对大数据处理的优化方案
2024-08-03

如何使用分区处理MySQL的亿级数据优化

mysql在查询上千万级数据的时候,通过索引可以解决大部分查询优化问题。但是在处理上亿数据的时候,索引就不那么友好了。 数据表(日志)是这样的:表大小:1T,约24亿行;表分区:按时间分区,每个月为一个分区,一个分区约2-3亿行数据(40-
2022-05-11

Golang函数性能优化之错误处理对性能的影响

错误处理会影响应用程序性能。以下优化措施可改善性能:避免 panic(),使用 error 值。使用 errors.new() 创建错误值。使用特定类型错误简化处理。使用 if err != nil {...} 模式处理错误。Golang
Golang函数性能优化之错误处理对性能的影响
2024-04-17

STL 函数对象在优化大型数据集处理中的作用?

使用 stl 函数对象可以显著优化大型数据集处理。stl 提供了许多函数对象,例如 std::function、std::bind、std::for_each、std::transform 和 std::sort,它们可以用来提升处理效率。
STL 函数对象在优化大型数据集处理中的作用?
2024-04-26

如何实现MySQL底层优化:查询优化器的工作原理及调优方法

如何实现MySQL底层优化:查询优化器的工作原理及调优方法在数据库应用中,查询优化是提高数据库性能的重要手段之一。MySQL作为一种常用的关系型数据库管理系统,其查询优化器的工作原理及调优方法十分重要。本文将介绍MySQL查询优化器的工作原
如何实现MySQL底层优化:查询优化器的工作原理及调优方法
2023-11-08

MySQL中的查询优化器工作原理解析

MySQL是一种常用的关系型数据库管理系统,广泛应用于各种Web应用程序和大型企业级系统中。在MySQL的日常使用中,查询语句是最常见和重要的操作之一。为了提高查询效率和性能,MySQL引入了查询优化器。查询优化器是MySQL内部的一个组件
2023-10-22

编程热搜

目录