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

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. ajax下载多文件,并且打包 C#中 ,文件批下载zip

    //提交要下载的文件 $.ajax({ url:"/sub/ZipFile.aspx", data:"paras="+datas, type: 'HEAD', ...

  2. 一步一步来做WebQQ机器人-(五)(发送消息||完结)

    × 本篇主要是: 发送QQ消息(to:好友,群),以及对小黄鸡抓包利用它的语言库 本文是WebQQ流程的最后一章 最后一章内容不多但我还是啰嗦,可能对大部分人都已知晓的流程方法我也会介绍一下 前面几个 ...

  3. Shell 重定向

    一直没搞懂 &> 和 <& 是表示什么意思. 今天自己总结一下,希望自己能理解它的真正含义. 重定向标准输入输出,切记 “1” 和 “>”之间没有空格 $ > ...

  4. Linux常用命令[转]

    在博客的草稿箱里一直有一份"Linux命令"的草稿,记录了一些常用的Linux命令,用于需要的时候查询.由于是出于个人使用的目的,所以这个清单并不完整.今天整理了一下这个清单,调整 ...

  5. 如何解决Visual Studio调试Debug很卡很慢

    http://brightguo.com/make-debugging-faster-with-visual-studio/ Have you ever been frustrated by slow ...

  6. Qt动画效果展示(文艺IT男)

    该程序使用应用程序单窗口,主窗口继承于QMainWindow:主窗口有5个QToolButton部件(窗口底部的四个以及窗口中央的一个),单击窗口底部的QToolButton部件可以使窗口中央的那个Q ...

  7. WPF 组合快捷键(Ctrl+C)

    页面程序: <Window x:Class="WpfDataGrid.Window1"        xmlns="http://schemas.microsoft ...

  8. WinServer2003 文件夹共享 方法设置

    文件夹设置: 5.假设我们在E盘有一个wmpub文件夹要设置在网络中共享,让大家都可以看到,首先我们右键点击WMPUB文件夹[共享和安全],弹出对话框,选择[共享此文件夹],点击[权限],弹出的对话框 ...

  9. Golang Import使用入门

    我们在写Go代码的时候经常用到import这个命令用来导入包文件,而我们经常看到的方式参考如下: import( "fmt" ) 然后我们代码里面可以通过如下的方式调用 fmt.P ...

  10. WP8.1 状态栏隐藏

    StatusBar statusbar = StatusBar.GetForCurrentView(); await statusbar.HideAsync();