相关的文档10bet官方网站 本手册下载 本手册节选

24.4分区修剪

这个优化被称为分区修剪是基于一个相对简单的概念,可以描述为不扫描没有匹配值的分区.假设有一个分区表t1由以下语句创建:

CREATE TABLE t1 (fname VARCHAR(50) NOT NULL, lname VARCHAR(50) NOT NULL, region_code TINYINT UNSIGNED NOT NULL, dob DATE NOT NULL)分区范围(region_code)(分区p0值小于(64),分区p1值小于(128),分区p2值小于(192),分区p3值小于MAXVALUE);

假设您希望从一个选择这样的陈述:

SELECT t1 WHERE region_code > 125 AND region_code < 130;

很容易看出,应该返回的行都不在两个分区中p0p3;也就是说,我们只需要在分区中进行搜索p1而且p2查找匹配的行。通过限制搜索,与扫描表中的所有分区相比,查找匹配行花费的时间和精力可能要少得多。这割掉不需要的分区称为修剪.当优化器在执行此查询时可以使用分区修剪时,查询的执行速度可能比对包含相同列定义和数据的非分区表执行相同查询快一个数量级。

优化器可以执行修剪每当在哪里Condition可以简化为以下两种情况之一:

  • partition_column常数

  • partition_column在(constant1constant2、……constantN

在第一种情况下,优化器只计算给定值的分区表达式,确定哪个分区包含该值,并只扫描该分区。在许多情况下,等号可以替换为另一种算术比较,包括<>< => =,<>.一些查询使用之间的在哪里子句还可以利用分区修剪。请参阅本节后面的示例。

在第二种情况下,优化器为列表中的每个值计算分区表达式,创建匹配分区的列表,然后只扫描该分区列表中的分区。

选择删除,更新语句支持分区修剪。一个插入语句也只能访问每个插入行的一个分区;即使对于由分割的表也是如此哈希关键虽然这目前没有显示在的输出中解释

修剪也可以应用于较短的范围,优化器可以将其转换为等价的值列表。例如,在前面的例子中在哪里子句可以转换为WHERE region_code IN (126, 127, 128, 129).然后优化器可以确定列表中的前两个值在分区中找到p1,分区中剩下的两个值p2其他分区不包含相关值,因此不需要搜索匹配的行。

的优化器还可以执行修剪在哪里使用的表的多个列上涉及前面类型的比较的条件范围列名单列分区。

当分区表达式包含一个等式或一个可以简化为一组等式的范围时,或者当分区表达式表示递增或递减关系时,就可以应用这种类型的优化。修剪还可以应用于在a上分区的表日期DATETIME列时,分区表达式使用年()TO_DAYS ()函数。类时,还可以对这类表应用修剪TO_SECONDS ()函数。

假设表t2在a上分割日期列,使用如下所示的语句创建:

CREATE TABLE t2 (fname VARCHAR(50) NOT NULL, lname VARCHAR(50) NOT NULL, region_code TINYINT UNSIGNED NOT NULL, dob DATE NOT NULL) PARTITION BY RANGE(YEAR(dob))(分区d0值小于(1970),分区d1值小于(1975),分区d2值小于(1980),分区d3值小于(1985),分区d4值小于(1990),分区d5值小于(2000),分区d6值小于(2005),分区d7值小于MAXVALUE);

以下语句使用t2可以用分区做修剪:

SELECT * FROM t2 WHERE dob = '1982-06-23';SET region_code = 8 WHERE dob BETWEEN '1991-02-15' AND '1997-04-25';WHERE dob >= '1984-06-21' AND dob <= '1999-06-21'

在最后一条语句的情况下,优化器还可以执行如下操作:

  1. 找到包含范围低端的分区

    (“1984-06-21”)收益率的值1984,在分区中找到d3

  2. 找到包含范围的高端的分区

    (“1999-06-21”)计算结果为1999,在分区中找到d5

  3. 只扫描这两个分区和它们之间的任何分区

    在本例中,这意味着只有分区d3d4,d5扫描。其余的分区可以被安全地忽略(也可以被忽略)。

重要的

无效的日期而且DATETIME中引用的在哪里的条件被处理为.这意味着查询,例如SELECT * FROMpartitioned_table在哪里date_column<“2008-12-00”不返回任何值(参见Bug #40972)。

到目前为止,我们只看了使用范围分区,但修剪也可以应用于其他分区类型。

考虑一个由。分割的表列表,其中分区表达式正在增加或减少,如表t3这里显示。(在本例中,为了简洁起见,我们假设region_code列的值限制在1到10之间(包括在内)。

CREATE TABLE t3 (fname VARCHAR(50) NOT NULL, lname VARCHAR(50) NOT NULL, region_code TINYINT UNSIGNED NOT NULL, dob DATE NOT NULL) PARTITION BY LIST(region_code) (PARTITION r0 VALUES IN (1,3), PARTITION r1 VALUES IN (2,5,8), PARTITION r2 VALUES IN (4,9), PARTITION r3 VALUES IN (6,7,10));

对于这样的语句SELECT * FROM t3 WHERE region_code在1和3之间,优化器确定在哪些分区中找到值1、2和3 (r0而且r1)并跳过其余的(r2而且r3).

对于由。划分的表哈希(线性)的关键的情况下,分区修剪也是可能的在哪里子句使用了简单的与分区表达式中使用的列的关系。考虑一个这样创建的表:

CREATE TABLE t4 (fname VARCHAR(50) NOT NULL, lname VARCHAR(50) NOT NULL, region_code TINYINT UNSIGNED NOT NULL, dob DATE NOT NULL)

比较列值和常量的语句可以被修剪:

UPDATE t4 WHERE region_code = 7;

修剪也可以用于短范围,因为优化器可以把这样的条件变成关系。例如,使用同一个表t4正如前面定义的,这样的查询可以被修剪:

SELECT * FROM t4 WHERE region_code < 6 AND region_code < 6;SELECT * FROM t4 WHERE region_code BETWEEN 3 AND 5;

在这两种情况下在哪里子句由优化器转换为WHERE region_code IN (3,4,5)

重要的

只有当范围大小小于分区数量时,才使用此优化。考虑一下这句话:

WHERE region_code在4到12之间

这个范围在哪里子句涵盖了9个值(4,5,6,7,8,9,10,11,12),但是t4只有8个分区。这意味着删除无法修剪。

当一个表被哈希(线性)的关键,修剪只能在整数列上使用。例如,这个语句不能使用修剪,因为强加于人是一个日期专栏:

SELECT * FROM t4 WHERE dob >= '2001-04-14' AND dob <= '2005-10-15';

但是,如果表将年值存储在INT列,则查询有WHERE year_col >= 2001 AND year_col <= 2005可以修剪。

表使用提供自动分区的存储引擎,例如NDBMySQL集群使用的存储引擎如果是显式分区,可以被修剪。