Chinaunix首页 | 论坛 | 博客
  • 博客访问: 17117
  • 博文数量: 22
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 240
  • 用 户 组: 普通用户
  • 注册时间: 2014-02-18 10:33
文章分类
文章存档

2015年(22)

我的朋友

分类: Mysql/postgreSQL

2015-03-01 12:16:15

    如果你重写查询使它们更有效率,或编写自己的应用程序逻辑进行查找,加入或排序,可以使用此信息来确定你自己写的优化,哪些是你可以依靠MySQL的执行。

1. 范围优化(Range Optimization)

    RANG[952]的访问方法是使用一个索引来检索所包含一个或多个索引值的时间间隔内表行的子集。它可用于单部分或多部分的索引。

1.1. 对于单部分指标的范围访问方法(The Range Access Method for Single-Part Indexes)

    对于单部分指标,指标值的时间间隔可以很方便地通过相应的条件,在WHERE子句中表示,所以我们讲的范围条件,而不是“intervals”。

    范围条件单部分指标的定义如下:
  • 对于这两个B树和哈希索引,具有恒定价值的关键组成部分的比较是一系列条件使用=[1233],<=>[1234],IN()[1236], IS NULL[1235],或者说是NOT NULL,[1235]运算符。

  • 此外,对于B树索引,具有恒定值的关键部分的比较是一系列条件使用>[1234],<[1234],>=[1234],<=[1234],Between[1235]!=[1234]或<>[1234]运算符,还是LIKE[1258]比较,如果该参数如[1258]是一个常量字符串不是以通配符。

  • 对于所有类型的索引,多个范围条件结合OR[1239]或AND[1239]形成了一系列的条件。

    “Constant value”在前面的描述是指下列操作之一:
  • 常量从查询字符串
  • 一列const[951]或system[951]来自同一个表连接。
  • 不相关子查询的结果。
  • 任何完全从前面类型的子表达式组成的表达式

    下面是与一系列条件的WHERE子句中的查询的一些例子:
        SELECT * FROM t1
            WHERE key_col> 1
            AND key_col< 10;

        SELECT * FROM t1
            WHERE key_col= 1
            OR key_colIN (15,18,20);

        SELECT * FROM t1
            WHERE key_colLIKE 'ab%'
            OR key_colBETWEEN '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');

    提取过程为键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')
  2. 除去nonkey= 4和KEY1 LIKE'%B',因为它们不能被用于一系列扫描。正确的方法将其删除是将其与TRUE替换,这样我们做的范围扫描时不会错过任何匹配的行。已经替换他们的话,我们得到:
    (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)总是为真。
    ? (key1 < 'uux' AND key1 > 'z')总是为假。
    更换这些条件与常数,我们可以得到:
    (key1 < 'abc' AND TRUE) OR (key1 < 'bar' AND TRUE) OR (FALSE)
    删除不必要的TRUE和FALSE常量,我们得到:
    (key1 < 'abc') OR (key1 < 'bar')
  4. 结合重复间隔为一个得到的最终状态,以用于范围扫描:
    (key1 < 'bar')

    在一般的(和主要表现在前面的例子中),用于范围扫描的条件比WHERE子句的限制较少。MySQL的执行额外的检查,以筛选出符合条件范围内的行,但不是完整的WHERE子句。

    范围条件提取算法可以处理嵌套AND[1239]/OR[1239]任意深度的结构,它的输出不依赖于哪些条件出现在WHERE子句中的顺序。

    目前,MySQL不支持空间索引的范围[952]访问方法合并多个范围。若要解决此限制,您可以使用一个UNION具有相同的SELECT语句,
除非你把每一个空间谓词的不同进行选择。

1.2 对于多部分索引的范围访问方法(The Range Access Method for Multiple-Part Indexes)

  缺少需要补充
阅读(227) | 评论(0) | 转发(0) |
0

上一篇:8.11. Optimizing the MySQL Server(优化MySQL服务)

下一篇:没有了

给主人留下些什么吧!~~