第二章 select语句优化 (二) —— 范围优化

范围访问方法 使用单个索引检索表行的子集 包含在一个或多个索引值区间内。它 可用于单部分或多部分索引。这 以下各节介绍 优化器使用范围访问。

  • 单部分索引的范围访问方法

  • 多部分索引的范围访问方法

  • 多值比较的相等范围优化

  • 跳过扫描范围访问方法

  • 行构造函数表达式的范围优化

  • 限制内存使用以实现范围优化

对于一个单一部分的指数、指数价值的时间间隔,可以方便地代表的相应条件,在其中的条款,表示为条件的范围,而不是"间隔时间。"

定义的范围条件对于一个单一部分的指数如下:

  • 对于这两b树和散列指标,比较的一个关键部分与常量值范围条件时使用=, <=>,在(),NULL,或是没有空运营商。

  • 此外,对于b树指标,比较的一个关键部分与常量值范围情况时使用>, <, >=, <=, 之间,!=, 或<>经营者,或者像比较,如果参数来像是一个不断串,不能启动用通 配符。

对于所有索引种类型、多条件的范围结合或并形成一系列条件。 "恒定值"在前面描述,意味着以下之一:

  • 一个恒定不变的查询字符串

  • 列的常数或系统表从相同的加入

  • 结果不相关的查询

  • 任何表达完全由从子表达式所述的类型

这里是一些例子查询有条件的范围在那里的条款:

SELECT * FROM t1
  WHERE key_col > 1
  AND key_col < 10;
​
SELECT * FROM t1
  WHERE key_col = 1
  OR key_col IN (15,18,20);
​
SELECT * FROM t1
  WHERE key_col LIKE 'ab%'
  OR key_col BETWEEN 'bar' AND 'foo';

一些非常量值可能会转换为常量,在优化的不断传播阶段。

MySQL试图提取条件的范围从其条款对于每个可能的索引。 在抽取过程中,条件,无法用于建造的范围,条件是下降,条件产生重叠的范围结合,条件,产生空的范围中删除。

考虑了以下声明,其键1是一种索引列和非键不是编制索引:

SELECT * FROM t1 WHERE
  (key1 < 'abc' AND (key1 LIKE 'abcde%' OR key1 LIKE '%b')) OR
  (key1 < 'bar' AND nonkey = 4) OR
  (key1 < 'uux' AND key1 > 'z');

提取过程中的关键键1如下:

  1. 开始与原来的那条款:

    (key1 < 'abc' AND (key1 LIKE 'abcde%' OR key1 LIKE '%b')) OR
    (key1 < 'bar' AND nonkey = 4) OR
    (key1 < 'uux' AND key1 > 'z')
  2. 除非键=4键1LIKE'%b',因为它们不能被用于一系列扫描。 正确的方式,以消除他们是代替他们与真正的,以使我们不错过任何匹配的行当做的范围内扫描。 替换他们与真正的产量

    (key1 < 'abc' AND (key1 LIKE 'abcde%' OR TRUE)) OR (key1 < 'bar' AND TRUE) OR (key1 < 'uux' AND key1 > 'z')
  3. 崩溃的条件总是真实的或假:

    (key1 LIKE 'abcde%' OR TRUE) is always true
    ​
    (key1 < 'uux' AND key1 > 'z') is always false 

    替换这些条件的常量产量:

    (key1 < 'abc' AND TRUE) OR (key1 < 'bar' AND TRUE) OR (FALSE)

    去除不必要的真假常产量:

    (key1 < 'abc') OR (key1 < 'bar')
  4. 合并重叠的间隔时间为一个产生的最终条件可用于范围扫描

    (key1 < 'bar')

在大(并且如前面的例子),条件用于一系列扫描限制较少的条款。 MySQL执行附加检查,以筛选出行满足范围的条件,但不是充满在条款。 范围条件下提取的算法可以处理嵌套和/或结构的任意深度,其输出不取决于为了在哪些条件下会出现在那里的条款。 MySQL不支持合并多个范围的范围内访问方法的空间索引。 要解决这个限制,可以使用一种联盟具有相同的选择声明,除了,你把每个空间谓词在不同的选择。 范围访问的方法为多个部分的索引 范围条件下,在多部分指数的扩展范围的条件对于一个单一部分的索引。 一系列条件,在多个部分的指标限制了索引行为的谎言内的一个或几个关键的多元组的时间间隔。 关键元组的时间间隔定义在一定的关键元组,使用订单的索引。 例如,考虑一个多部分指数定义为键1(key_part1,key_part2,key_part3),并以下列关键组中列出的关键顺序:

key_part1  key_part2  key_part3
  NULL       1          'abc'
  NULL       1          'xyz'
  NULL       2          'foo'
   1         1          'abc'
   1         1          'xyz'
   1         2          'abc'
   2         1          'aaa'

条件key_part1=1规定了这种时间间隔:

(1,-inf,-inf) <= (key_part1,key_part2,key_part3) < (1,+inf,+inf)

间隔涵盖了第4、第5和第6组中所述的数据集和可以使用的范围内访问的方法。 相反,条件key_part3='abc'并不界定一个单一的间隔而无法使用的范围内访问的方法。 下面的说明表明如何范围的条件下工作多部分中的索引更详细的说明。 哈希指标,每隔含有相同的价值观可以使用。 这意味着间隔可能只产生的条件在以下形式:

    key_part1 cmp const1
AND key_part2 cmp const2
AND ...
AND key_partN cmp constN;

在这里,const1,const2、...是常数,《议定书》缔约方会议的一=,<=>,或是空的比较符,条件涵盖所有索引部分。 (即,有N条件下,每个部分的一个N的一部分索引。) 例如,以下是一系列条件,用于一个三部分的散列指数:

key_part1 = 1 AND key_part2 IS NULL AND key_part3 = 'foo'

为什么的定义被认为是一个常量,请参阅范围内访问方法的单一部分的索引。 对于b树指数,间隔时间可能是有用的条件结合,并在每个情况进行比较的一个关键部分与常量值使用=,<=>,NULL, >, <, >=, <=, !=, <>, 之间,或者像'模式'(其中,'模式'不能启动用通配符)。 一个间隔时间可以使用,只要它能够确定一个单一的关键元组包含的所有行匹配的条件(两间隔如果<>或!= 是使用)。 优化的尝试使用其他关键部件确定的间隔时间,只要比较算是=,<=>,或是空。 如果运营商是>, <, >=, <=, !=, <>, 之间,或如,优化使用,但认为没有更多的关键部分。 对于下面的表达,优化使用=从第一次比较。 它还使用>=从第二比较,但认为没有进一步的关键部件,并没有使用第三比较为间隔的建设:

key_part1 = 'foo' AND key_part2 >= 10 AND key_part3 > 10

单一的间隔时间为:

('foo',10,-inf) < (key_part1,key_part2,key_part3) < ('foo',+inf,+inf)

这是可能的创建时间间隔包含更多的行比最初的条件。 例如,所述的间隔时间,包括价值("foo",11,0),它不满足原来的状态。 如果条件,涵盖套行包含在间隔时间的结合或者,它们形成一个条件,涵盖了一组行内包含的联盟他们的时间间隔。 如果条件合并,它们形成一个条件,涵盖了一组行内包含的交叉点自己的时间间隔。 例如,对于这种情况上一个两部分指数:

(key_part1 = 1 AND key_part2 < 2) OR (key_part1 > 5)

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

杨慕晨

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值