mysql用in查询list_Mysql优化器对in list的处理

select * from table where id in (....)

这样的查询,是走范围索引还是走等值索引?

select * from table where key_part1 in (....) and key_part2='XX';

这样的查询,第二部分还走不走索引?

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

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” 的“多个等值”查询来处理的;并没有转成范围查询 ;

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/299228.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

开源软件通识基础:第二周课程回顾与总结

接第一篇《开源软件通识基础:第一周课程回顾与总结》,本文为第二周课程内容的回顾与总结。本导学班在调研全球开源教育与课程的基础上,通过收集、整理、理解、拓展国际最新的前沿开源课程,采取众创的模式,由 X-lab 核心…

心情分享

很快,毕业半年多了也工作半年了。回过头想想这段时间更多的是思考,想说的是自己的认识,能做的只有更加的努力。现在都把大学生和民工做比较,甚至有人说大学生还不如民工。是对还是错?谁的错,没有衡量的依据…

mysql数据连接查询_mysql数据库 连接查询

左连接:select 列1,列2,列N fromtableA left join tableBon tableA.列 tableB 【此次表连接成一张大表,完全当成普通表看】where group ,having...照常写例:select goods_id,goods.cat_id,cat_name,goods_name,sho…

在DataGrid中合并单元格行

最近在做项目的时候经常遇到要合并单元格的情况,发现这个东西.net中并没有现成的方法,研究了一下,总结了两种方法。 这个主要都是行合并的,有以下两种情况 1、多行合并为一行,其中将某个或某几个单元格的内容合并起来 …

封装log4cp p

log4cpp 是参考 log4j 所写的 c 版本的写 log 的库。可以在这里下载http://log4cpp.sourceforge.net/我的使用方法是:1,定义了一个 _LOG4CPP 宏,用来打开或关闭 log4cpp 的调用,以便在完全不需要 log 的情况下可以运行&#xff0c…

这些口碑炸裂的BBC神片,就是给孩子最好的生命教育

全世界只有3.14 % 的人关注了爆炸吧知识对孩子来说,好的纪录片就像是打开了一扇新世界的大门,让他们了解了更多大自然的奇妙之处。所以这次我们精心挑选了几部适合儿童观看的纪录片,其中绝大多数是导演专门为孩子拍摄的,大家可以在…

依赖注入生命周期

介绍依赖注入只负责由其创建的对象实例容器或者子容器释放的时候,会释放由其创建的对象实例。推荐使用容器来来管理我们的对象的创建和释放。操作为了演示,我们创建一个UserService,并让该Service继承IDisposablepublic class UserService : …

常用网络面试题一

1、 win2000,win2003个有几个版本,每个版本最新系统补丁包是什么啊? 2、 DNS的实现方法? 3、 WEB服务器的负载均衡? 4、 请问目前市面上常用几种网络操作系统的优缺点? 5、 请问你用过那些服务器?请讲述rai…

《划时代-51单片机C语言全新教程》-第四章 工程创建与深入 概览

(请复制整个下载地址到迅雷、快车、QQ旋风进行下载) 电子书下载地址:http://files.cnblogs.com/wenziqi/划时代-51单片机C语言全新教程.rar转载于:https://www.cnblogs.com/wenziqi/archive/2010/07/05/1771281.html

java模拟火车站买票的过程_Java常用代理

在我们通常的应用中,代理模式也是我们常用的设计模式之一。所谓的代理模式是指客户端并不直接调用实际的对象,而是通过调用代理对象,来间接的调用实际的对象。为什么要采用这种间接的形式来调用对象呢?一般是因为客户端不想访问实…

网络繁杂,我们该如何准确获取所需信息?

全世界只有3.14 % 的人关注了爆炸吧知识网络已经成为了很多人发表言论的地方不少网站亦难免存在宣泄情绪的内容网络繁杂,该如何获取准确信息?下面为你推荐一些客观公号希望能让你扩展视野,增长见识!【关注方式 】1 - 搜索公众号ID…

.NET 6 新特性 WaitAsync

.NET 6 新特性 WaitAsyncIntro在 .NET 6 里新增加了一个 WaitAsync 的方法,用来异步地等待一个任务完成,异步等待的时候可以指定一个 Timeout 时间或者一个取消令牌 CancellationToken,在之前的版本中只有一个同步的 Wait 会等待任务的完成&a…

局域网dos命令集

开启服务命令:net start 服务名信使服务:先开启messenger服务。net send ip "消息文本"局域网dos命令集ls命令是我们常用的几个命令,但是其中有一些很有用的参数我们往往不是很清楚,现在介绍如下: -t -c 按照…

优秀编程网站收录集锦

陆续更新中,敬请关注: 中国开源网:http://www.yuanma.org/ 编程爱好者:http://blog.pfan.cn/vfdff/33993.html 全国嵌入式人才培训基地: http://learn.akae.cn/media/ch21s03.html 转载于:https://www.cnblogs.com/Jessy/archive…

jdbc连接mysql的语法_JDBC连接MySQL

JDBC连接MySQL加载及注册JDBC驱动程序Class.forName("com.mysql.jdbc.Driver");Class.forName("com.mysql.jdbc.Driver").newInstance();JDBC URL定义驱动程序与数据源之间的连接标准语法:::MySQL的JDBCURL格式:jdbc:mysql//[hostna…

被评为“影响世界千年的物理学家”,杨振宁的伟大,你根本不了解

全世界只有3.14 % 的人关注了爆炸吧知识2018年3月14日,英国科学家霍金去世,作为当代英国最杰出的科学家之一,英国用最规格的方式送别了这位伟大的科学家。霍金去世了,中国媒体沸腾了!有人说:这是全人类的损…

[1197]约瑟夫问题 (循环链表)SDUT

约瑟夫问题 Time Limit: 1000ms Memory limit: 65536K 有疑问?点这里^_^ 题目描述 n个人想玩残酷的死亡游戏,游戏规则如下: n个人进行编号,分别从1到n,排成一个圈,顺时针从1开始数到m,数到m…

Blazor+Dapr+K8s微服务之服务调用

1.1 Dapr环境配置1.1.1 在开发机安装Docker Desktop并启用Kubernetes安装过程略,安装好后效果如下:(左下角两个绿色指示Docker和K8s正在运行)1.1.2 在开发机安装Dapr Cli安装命令:powershell -Command …

squid2.6加速WEB支持虚拟主机配置心得体会 .txt

人一台web服务器,日流量约10万,上面有好几个虚拟主机,近日装上Squid 2.6进行WEB加速,Squid 和Apache均在同一台服务器上面,效果非常明显,看到论坛上好多人问如何配置squid2.6支持,虚拟主机现在将安装过程贴…

IT职涯路

在51cto周刊上发现了这篇文章,不错,转载过来~~ 前段时间看了一篇文章,叫做《IT人为什么难以拿高薪》,颇有感触,于是写下这篇文章,希望与各位XDJM共勉~ 能够看到这个帖子的每个XDJM,…