8.2.1.3 Range Optimization 范围优化

来源:互联网 发布:中国保险网络大学注册 编辑:程序博客网 时间:2024/04/30 08:48

8.2.1.3 Range Optimization 范围优化

范围访问方法使用一个单独的索引来取回一个表记录的子集, 包含在一部分或者多个部分, 索引值区间。它可用于

单部分或者多部分 索引,下面的章节给出:

8.2.1.3.1 The Range Access Method for Single-Part Indexes

对于一个单一部分的索引,索引值区间可以方便的 表示通过相应的条件在WHERE 子句里,

因此我们将范围条件相比 “时间间隔”

range 条件的定义用于单部分索引如下;

对于B树和HASH 索引, key part和一个常值是一个范围条件使用= ,<=>,in(),IS NULL 或者IS NOT NULL操作。

对于所有类型的索引,多个range 条件组成用OR 或者AND

在前面的描述中 常量值 指下面的:

  1. 查询字符串常量

2.const或者system表的列 从相同的join

3.一个无关联的子查询的结果

4.任何表达式完整的从 先前的类型的子表达式组成

这里有一些查询的例子, range 条件在WHERE 子句:

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 试图提取范围条件从WHERE 语句中,对于每个可能的索引。

在提取过程中,条件不能用于构造范围条件会被丢弃,产生重叠范围的条件相结合,和产生的条件,产生空的范围被删除。

考虑下面的语句,其中key1 是一个索引列和nonkey 没有被索引:

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’);

对于key key1的提取过程如下:

1.开始原始的WHERE 子句:

(key1 < ‘abc’ AND (key1 LIKE ‘abcde%’ OR key1 LIKE ‘%b’)) OR
(key1 < ‘bar’ AND nonkey = 4) OR
(key1 < ‘uux’ AND key1 > ‘z’)

  1. 移除nonkey=4 和 key1 LIKE ‘%b’ ,因为他们不使用range scan, 正确的移除它们是替换它们,

因此我们不会丢失任何匹配的行,当做range scan的时候, 替换它们为TRUE,我们得到:

(key1 < ‘abc’ AND (key1 LIKE ‘abcde%’ OR TRUE)) OR
(key1 < ‘bar’ AND TRUE) OR
(key1 < ‘uux’ AND key1 > ‘z’)

崩溃的条件,总是TRUE或者FALSE:

(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)

删除不西药的TRUE和FALSE常值,我们得到:

(key1 < ‘abc’) OR (key1 < ‘bar’)

结合重叠的时间间隔到一个区域,最后的条件是用于range scan:

(key1 < ‘bar’)

在一般的情况下(如前面的例子所证明的),用于range scan 的条件越少 ,Mysql 执行额外的检查来过滤我们的记录,

满足range 条件,但不是整个where 子句。

范围条件提取算法能处理 nested AND/OR 结构的任意深度,其输出不依赖于该条件出现在何处的顺序。

8.2.1.3.2 The Range Access Method for Multiple-Part Indexes 多个部分访问的范围访问

range 条件在多个部分index 是一个扩展的range 条件对于一个单部分的index,

一个range 条件在多个部分index 限制index 记录位于一个或者多key 元素区间:

例如, 考虑一个多部分索引定义为key1(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 元组 在前面的数据集 可以通过range 访问方法:

相比之下, 条件 key_part3 = ‘abc’ 没有定义一个群件,不能通过访问访问方法:

下面的描述说明如何在更详细的情况下多个部分索引的范围条件如何工作。

对于HASH 索引, 每个间隔包含相同的值,这意味着 间隔可以产生只在下面的情况:

key_part1 cmp const1

AND key_part2 cmp const2
AND …
AND key_partN cmp constN;

cmp 比较符

在这里,const1,const2,……是常数,CMP是一个=,< = >,或是空的比较运算符,和条件覆盖所有指标部分。(即,有条件的,一个正部分的指标。各部分)为例,下面是一三部分的哈希索引范围条件:

key_part1 = 1 AND key_part2 IS NULL AND key_part3 = ‘foo’

对于B树索引,一个区间可能是可用是使用AND的条件结合, 每个条件比较一个key 用一个常值使用

=, <=>, IS NULL, >, <, >=, <=, !=, <>, BETWEEN, or LIKE ‘pattern’(模式不以%开头)

一个内部可以用于只要它是可能的去顶一个单独的key 元组包含所有的记录匹配条件.

优化器尝试使用额外的key parts 来确定内部的只要是比较操作符 =, <=>, or IS NULL

如果 操作符是>, <, >=, <=, !=, <>, BETWEEN, or LIKE,优化器使用它但是不考虑key parts.

对于下面的表达式,优化器使用从第一个比较, 它使用>= 从第2次比较,但是没有进一步key pars:

key_part1 = ‘foo’ AND key_part2 >= 10 AND key_part3 > 10

单间隔是:

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

8.2.1.3.3 Equality Range Optimization of Many-Valued Comparisons (多值比较的平等的range 优化)

考虑到那些条件,当col_name 是一个索引列:

col_name IN(val1, …, valN)

col_name = val1 OR … OR col_name = valN

如果表达式是真的, 如果col_name 是等于任何数值。这些比较是平等的范围比较( 当”range”是一个单独值)

优化器评估的成本:

如果col_name有唯一索引, 每个范围的评估行是1,因为最后返回一行

否则, 优化器可以使用潜在的索引和索引统计信息来评估每个range 的行数。

随着潜在的索引,优化器在每个range的尽头,使用在range 范围作为评估的行。比如,

表达式 col_name(10,20,30) 有3个平等的ranges。

0 0
原创粉丝点击