我们在写sql的时候,经常用到in,in后面跟一堆常量列表,如id。有人说in的效率很高,而有人说很低;有人说in能使用索引,还有人说in不能使用索引。。。
到底是一个怎样的情况呢?我们分析以下几种情况
在这之前,我们先了解一下explain的几种type类型(本次分析即参照type类型),按照性能从高到低:

const:表中的一个记录的最大值能够匹配这个查询(索引可以是主键或惟一索引)。因为只有一行,这个值实际就是常数,因为MYSQL先读这个值然后把它当做常数来对待

eq_ref:在连接中,MYSQL在查询时,从前面的表中,对每一个记录的联合都从表中读取一个记录,它在查询使用了索引为主键或惟一键的全部时使用

ref:这个连接类型只有在查询使用了不是惟一或主键的键或者是这些类型的部分(比如,利用最左边前缀)时发生。对于之前的表的每一个行联合,全部记录都将从表中读出。这个类型严重依赖于根据索引匹配的记录多少—越少越好

range:这个连接类型使用索引返回一个范围中的行,比如使用>或<查找东西时发生的情况

index: 这个连接类型对前面的表中的每一个记录联合进行完全扫描(比ALL更好,因为索引一般小于表数据)

ALL:这个连接类型对于前面的每一个记录联合进行完全扫描,这一般比较糟糕,应该尽量避免

一,in后面只有1个值
1.1 对于主键或者唯一索引,那么type=const,这种性能最高,表示表中只有1个记录能满足查询

1.2 对于普通索引、或者联合主键,type=ref

1.3 对于普通字段,type=all,这种性能最差

二,in后面多余1个值,但少于某一个值,这个值具体是多少,之后会揭晓。
这时,不管是主键,还是唯一索引,还是普通索引,type=range

但是在这里需要注意的一个特例是:当你的索引的Cardinality属性比较低时,type=all,意思就是这个索引的区分度很低,建立的意义不大,
这时他的执行计划type=all,mysql认为走这个索引还不如全表扫描:

到底Cardinality处于什么水平时,性能最好?一般认为这个值越接近count(*),性能最好。而对于像性别这种字段,就没必要加索引了。

三,相对于第二种情况,当in后面的值多于某一个值,会导致扫描全表。这个经验值我目前不能确定,咨询过相关DBA,他们也不能给出其经验值
3.1 test1表总共27条数据,当in后面的值少于8个时,type=range,而当超过8个时,type=all,如下:

3.2 这个t_word_cost表,总共有38244条数据,word_id上有索引,我测试了一把,当in后面不超过5千多或者6千多时,type=range,这是什么意思?
因为令我不解的是,这个值还不确定,它是波动的,我执行了好多次,有时候是5千多,有时候是6千多,或者其他值

通过对test1、t_word_cost表进行测试,我确实没有找出规律来,我原来妄想,通过大量实践得出一个经验值,然后通过经验值来判断到底in后面的个数占count(*)百分比多少的时候,能走索引,看来我徒劳了。

既然不能得出经验值,那我们只有在实际应用环境下具体选择解决方案了。
譬如我这次操作t_word_cost表,in后面值的个数都超过count(*)了,如果一次性全部写进in后面,一次查询所耗时间是30-40s左右!
根据上面我分析的结果,貌似我应该选择5000作为临界值,然后分批、多次查询,这样性能应该最高。但实际情况是这样吗?
通过我在程序中不断地人肉测试发现,并不是5000耗时最少,选择2000或者2500时,总体耗时最少,至于为什么,可能与内存、频繁的数据库连接有关吧,
因为我们知道,内存、IO都会影响整体性能,所以怎样平衡这个度需要自己把握。

MySQL中in(常量列表)的执行计划的更多相关文章

  1. [转]Mysql中的SQL优化与执行计划

    From : http://religiose.iteye.com/blog/1685537 一,如何判断SQL的执行效率? 通过explain 关键字分析效率低的SQL执行计划. 比如: expla ...

  2. Mysql中的sql是如何执行的 --- 极客时间学习笔记

    MySQL中的SQL是如何执行的 MySQL是典型的C/S架构,也就是Client/Server架构,服务器端程序使用的mysqld.整体的MySQL流程如下图所示: MySQL是有三层组成: 连接层 ...

  3. MySQL——通过EXPLAIN分析SQL的执行计划

    在MySQL中,我们可以通过EXPLAIN命令获取MySQL如何执行SELECT语句的信息,包括在SELECT语句执行过程中表如何连接和连接的顺序. 下面分别对EXPLAIN命令结果的每一列进行说明: ...

  4. 高性能可扩展mysql 笔记(六) SQL执行计划及分页查询优化、分区键统计

    个人博客网:https://wushaopei.github.io/    (你想要这里多有) 常见业务处理 一.使用数据库处理常见业务: 案例: 如何对评论进行分页展示 使用 EXPLAIN 获得s ...

  5. Mysql中explain命令查看语句执行概况

    Mysql中可以使用explain命令查看查询语句的执行方式,使用方法举例:explain + 查询语句 例如:explain select * from user_info 几个重要的字段说明: t ...

  6. Mysql学习---视图/触发器/存储过程/函数/执行计划/sql优化 180101

    视图 视图: 视图是一个虚拟表(非真实存在),动态获取数据,仅仅能做查询操作 本质:[根据SQL语句获取动态的数据集,并为其命名],用户使用时只需使用[名称]即可获取结果集,并可以将其当作表来使用.由 ...

  7. oracle中查看sql语句的执行计划

    1.在pl/sql中打开cmd命令容器 2.在cmd命令窗口中输入:explain plan for select * from t; 3.查看sql语句的执行计划:select * from tab ...

  8. [转]使用mysql profiles 来查看sql 语句执行计划

    From : http://blog.csdn.net/radkitty/article/details/4632289 要使用该功能,mysql的版本必须在5.0.37版本以上.否则只能使用expl ...

  9. mysql中插入序列表

    利用序列表来实现列转行:CREATE TABLE sequence(id INT UNSIGNED NOT NULL auto_increment PRIMARY KEY)往里面插入数据 INSERT ...

  10. MySQL 查看执行计划

    MySQL 使用 explain + sql 语句查看 执行计划,该执行计划不一定完全正确但是可以参考. EXPLAIN SELECT * FROM user WHERE nid = 3; selec ...

随机推荐

  1. Python与数据库[1] -> 数据库接口/DB-API[3] -> ODBC 适配器

    ODBC适配器 / ODBC Adaptor ODBC(Open Database Connectivity,开放数据库互连)是微软公司开放服务结构(WOSA,Windows Open Service ...

  2. poj3254(状态压缩DP)

    poj3254 题意 给出一个01矩阵,1表示当前这个位置可以放牛,要求放牛的方案保证牛不能左右或上下相邻,求方案数. 分析 dp[S][i]: 表示到 i 行时的状态S(用二进制数表示),那么状态转 ...

  3. 腾讯消消乐 (状态压缩DP)

    腾讯消消乐 题意 给出长度为 n 的序列,每次可以选择删除序列的一个连续区间,要求这一段区间内所有数最大公约数不小于 k ,删除后剩下的序列仍然构成连续序列. 定义 f(i) 为进行 i 次操作将整个 ...

  4. 中国石油大学(华东)OJ题目的HTML爬取

    这几天刷华东OJ的题,写博客还要复制HTML的代码,感觉麻烦的一批,然后就去摸鱼写了个小爬虫.. 看一下运行效果吧- 输入详细的pid.cid或id即可爬取相应的html代码 一些注意要点: 关键的还 ...

  5. POJ 2100:Graveyard Design(Two pointers)

    [题目链接] http://poj.org/problem?id=2100 [题目大意] 给出一个数,求将其拆分为几个连续的平方和的方案数 [题解] 对平方数列尺取即可. [代码] #include ...

  6. !!!!Linux系统开发 系列 4 进程资源 环境 fork()子进程 wait() waitpid()僵尸 孤儿进程

    http://990487026.blog.51cto.com/10133282/1834893

  7. ASIHTTPRequest学习(三)

    刚刚开始学习ASIHttpRequest,今天通过自己写的一个小demo分享一下学习心得. 首先,要想在ios项目中使用ASIHttpRequest,必须添加下列框架和类库: ASIHttpReque ...

  8. ulimit 不生效

    ulimit is a shell builtin like cd, not a separate program. sudo looks for a binary to run, but there ...

  9. DotnetBrowser高级教程-(4)使用MVC框架3-文件上传

    网站有时候需要上传文件,本节以上传一张图片为例,在UserController.cs里添加如下代码: public string UploadImgPage() { return "< ...

  10. 记录一次ceph recovery经历

    一次ceph recovery经历 背景 这是一个測试环境. 该环境中是cephfs 一共12个节点, 2个client.2个mds.8个osd mds: 2颗CPU,每一个4核.一共是8核. 128 ...