在以往的分享中,不止一次被开发问:

MySQL的官方手册上有这么一句话:

the optimizer can estimate the row count for each range using dives into the index or index statistics.

这是在说: 优化器为每一个范围段(如“a IN (10, 20, 30)”是等值比较, 括3个范围段实则简化为3个单值,分别是10,20,30)估计每个范围段(用范围段来表示是因为MySQL的“range”扫描方式多数做的是范围扫描,此处单值可视为范围段的特例)中包括的元组数, 而估计方法有2种,一是dive到index中即利用索引完成元组数的估算,简称index dive; 二是使用索引的统计数值,进行估算:

相比这2种方式,在效果上:

1 index dive: 速度慢,但能得到精确的值(MySQL的实现是数索引对应的索引项个数,所以精确)

2 index statistics: 速度快,但得到的值未必精确

简单说,选项 eq_range_index_dive_limit 的值设定了 IN列表中的条件个数上线,超过设定值时,会将执行计划从 1 变成 2。

为什么要区分这2种方式呢?

简单地说:

1 查询优化器使用代价估算模型计算每个计划的代价,选择其中代价最小的

2 单表扫描时,需要计算代价;所以单表的索引扫描也需要计算代价

3 单表的计算公式通常是:代价=元组数*IO平均值

4 所以不管是哪种扫描方式,都需要计算元组数

5 当遇到“a IN (10, 20, 30)”这样的表达式的时候,发现a列存在索引,则需要看这个索引可以扫描到的元组数由多少而计算其索引扫描代价,所以就用到了本文提到的“index dive”、“index statistics”这2种方式。

MySQL据此,提供了一个参数“eq_range_index_dive_limit”,指示MySQL在这种情况下使用哪种方式。用法如下:

This variable indicates the number of equality ranges in an equality comparison condition when the optimizer should switch from using index dives to index statistics in estimating the number of qualifying rows. It applies to evaluation of expressions that have either of these equivalent forms, where the optimizer uses a nonunique index to look up col_name values:

col_name IN(val1, ..., valN)

col_name = val1 OR ... OR col_name = valN

默认设置是10,一直到5.7以后的版本默认会修改成200,当然我们是可以手动设置的。我们看下5.6手册中的说明:

The eq_range_index_dive_limit system variable enables you to configure the number of values at which the optimizer switches from one row estimation strategy to the other. To disable use of statistics and always use index dives, set eq_range_index_dive_limit to 0. To permit use of index dives for comparisons of up to N equality ranges, set eq_range_index_dive_limit to N + 1.
eq_range_index_dive_limit is available as of MySQL 5.6.5. Before 5.6.5, the optimizer uses index dives, which is equivalent to eq_range_index_dive_limit=0.

也就是说:

1. eq_range_index_dive_limit = 0 只能使用index dive
2. 0 < eq_range_index_dive_limit <= N 使用index statistics
3. eq_range_index_dive_limit > N 只能使用index dive

AliSQL的配置:

参考资料:

http://myrock.github.io/2014/09/24/in-and-range/

http://blog.163.com/li_hx/blog/static/18399141320147521735442/

让我轻轻的告诉你AliSQLselect语句中in多少个合适的更多相关文章

  1. mysql查询语句中使用星号真的慢的要死?

    前言 之所以写这篇文章,是源于以前看过的关于sql语句优化的帖子,里面明确提到了在sql语句中不要使用 * 来做查询,就像下面的规则中说的 2.尽量避免使用select *,返回无用的字段会降低查询效 ...

  2. continue语句在for语句和while语句中的区别

    while语句的形式: while( expression ) statement for语句的形式: for( expression1; expression2;expression3 )   // ...

  3. LINQ语句中的.AsEnumerable() 和 .AsQueryable()的区别

    LINQ语句中的.AsEnumerable() 和 .AsQueryable()的区别 在写LINQ语句的时候,往往会看到.AsEnumerable() 和 .AsQueryable() .例如: s ...

  4. 【转】Java中try catch finally语句中含有return语句的执行情况(总结版)

    Java中try catch finally语句中含有return语句的执行情况(总结版) 有一点可以肯定,finally块中的内容会先于try中的return语句执行,如果finall语句块中也有r ...

  5. sql语句中----删除表数据drop、truncate和delete的用法

    sql语句中----删除表数据drop.truncate和delete的用法 --drop drop table  tb   --tb表示数据表的名字,下同 删除内容和定义,释放空间.简单来说就是把整 ...

  6. if语句中的判断条件(nginx)

    if语句中的判断条件   正则表达式匹配:     ==:等值比较;     ~:与指定正则表达式模式匹配时返回"真",判断匹配与否时区分字符大小写:     ~*:与指定正则表达 ...

  7. include包含头文件的语句中,双引号和尖括号的区别是什么?

    include包含头文件的语句中,双引号和尖括号的区别是什么?  #include <> 格式:引用标准库头文件,编译器从标准库目录开始搜索 尖括号表示只在系统默认目录或者括号内的路径查找 ...

  8. MySQL语句中的转义字符----引号

    MySQL语言中的转义字符和各种编程语言基本相同,见下表 形式 含义 \0 0(NUL)字符 \n 换行 \r 回车符 \t 制表符 \b 退格 \' 单引号 \" 双引号 \\ 反斜线 \ ...

  9. using 语句中使用的类型必须可隐式转换为“System.IDisposable

    在使用 EF 出现 using 语句中使用的类型必须可隐式转换为“System.IDisposable 今天写在这里分享给大家 出现这样的问题,是因为没有引用  EntityFramework 这个程 ...

随机推荐

  1. 将博客从jekyll迁移到了hexo

    关于hexo和jekyll hexo和jekyll一样都是个静态网站生成工具,hexo是一个台湾小伙使用nodejs开发的,jekyll则是用ruby开发,github内置了jekyll,可以直接将j ...

  2. bahuanghou111

    #include<stdio.h> int map[8][8]={0}; int count=0; int safe(int x,int y) { int i; int j; for(i= ...

  3. C++中函数变量布局小结

    把布局作为一种信仰(Layout as Religion).                                                                       ...

  4. Kafka 解析

    Kafak采用硬盘顺序写入和内存映射文件技术提示性能.即便是顺序写入硬盘,硬盘的访问速度还是不可能追上内存.所以Kafka的数据并不是实时的写入硬盘,它充分利用了现代操作系统分页存储来利用内存提高I/ ...

  5. ASP.NET MVC 项目中 一般处理程序ashx 获取Session

    1-在 aspx和aspx.cs中,都是以Session["xxx"]="aaa"和aaa=Session["xxx"].ToString( ...

  6. Emacs 16进制模式

    http://blog.163.com/lan_ne/blog/static/1926701702012112272840545/ ALT+X hexl-mode   进入16进制模式 在这一模式,直 ...

  7. 申请使用aws的一些笔记

    1. 申请可以使用asw.amazon.com/cn/,这个界面虽然是中文的,但是申请的是海外的aws. 2. 审核后会收到如下的一封邮件: 3. 剩下创建EC2和RDS的过程可以参考http://w ...

  8. Windows Internal Database Service Pack 4 x64 Edition (KB2463332)安装失败

    系统是Windows Server 2008 R2,补丁Windows Internal Database Service Pack 4 x64 Edition (KB2463332)总是安装失败,W ...

  9. python之路 目录

    目录 python python_基础总结1 python由来 字符编码 注释 pyc文件 python变量 导入模块 获取用户输入 流程控制if while python 基础2 编码转换 pych ...

  10. git pull 冲突解决

    这个意思是说更新下来的内容和本地修改的内容有冲突,先提交你的改变或者先将本地修改暂时存储起来. 处理的方式非常简单,主要是使用git stash命令进行处理,分成以下几个步骤进行处理. 1.先将本地修 ...