MySQL Order By索引优化方法

尽管 ORDER BY
不是和索引的顺序准确匹配,索引还是可以被用到,只要不用的索引部分和所有的额外的
ORDER BY 字段在 WHERE 子句中都被包括了。 使用索引的MySQL Order By
下列的几个查询都会使用索引来解决 ORDER BY 或 GROUP BY 部分: 复制代码 代码如下: SELECT * FROM t1 ORDER BY
key_part1,key_part2,… ; SELECT * FROM t1 WHERE key_part1=constant
ORDER BY key_part2; SELECT * FROM t1 WHERE key_part1=constant GROUP
BY key_part2; SELECT * FROM t1 ORDER BY key_part1 DESC, key_part2
DESC; SELECT * FROM t1 WHERE key_part1=1 ORDER BY key_part1 DESC,
key_part2 DESC; 不使用索引的MySQL Order By
在另一些情况下,MySQL无法使用索引来满足 ORDER
BY,尽管它会使用索引来找到记录来匹配 WHERE 子句。这些情况如下: *
对不同的索引键做 ORDER BY : SELECT * FROM t1 ORDER BY key1, key2; *
在非连续的索引键部分上做 ORDER BY: SELECT * FROM t1 WHERE
key2=constant ORDER BY key_part2; * 同时使用了 ASC 和 DESC: SELECT *
FROM t1 ORDER BY key_part1 DESC, key_part2 ASC; *
用于搜索记录的索引键和做 ORDER BY 的不是同一个: SELECT * FROM t1 WHERE
key2=constant ORDER BY key1; * 有很多表一起做连接,而且读取的记录中在
ORDER BY 中的字段都不全是来自第一个非常数的表中。 * 使用了不同的 ORDER
BY 和 GROUP BY 表达式。 * 表索引中的记录不是按序存储。例如,HASH 和
HEAP 表就是这样。 通过执行 EXPLAIN SELECT … ORDER
BY,就知道MySQL是否在查询中使用了索引。如果 Extra 字段的值是 Using
filesort,则说明MySQL无法使用索引。详情请看”7.2.1 EXPLAIN Syntax (Get
Information About a SELECT)”。当必须对结果进行排序时,MySQL 4.1以前
它使用了以下 filesort 算法: 复制代码
代码如下: 1. 根据索引键读取记录,或者扫描数据表。那些无法匹配 WHERE
分句的记录都会被略过。 2.
在缓冲中每条记录都用一个‘对’存储了2个值。缓冲的大小依据系统变量
sort_buffer_size 的值而定。 3. 当缓冲慢了时,就运行
qsort并将结果存储在临时文件中。将存储的块指针保存起来。 4.
执行上面的操作,直到所有的记录都读取出来了。 5. 做一次多重合并,将多达
MERGEBUFF个区域的块保存在另一个临时文件中。重复这个操作,直到所有在第一个文件的块都放到第二个文件了。

  1. 重复以上操作,直到剩余的块数量小于 MERGEBUFF2 (15)。 7.
    在最后一次多重合并时,只有记录的指针写到结果文件中去。 8.
    通过读取结果文件中的记录指针来按序读取记录。想要优化这个操作,MySQL将记录指针读取放到一个大的块里,并且使用它来按序读取记录,将记录放到缓冲中。缓冲的大小由系统变量
    read_rnd_buffer_size 的值而定。这个步骤的代码在源文件
    `sql/records.cc’ 中。
    这个逼近算法的一个问题是,数据库读取了2次记录:一次是估算 WHERE
    分句时,第二次是排序时。尽管第一次都成功读取记录了,第二次是随机的读取。在MySQL
    4.1 及更新版本中,filesort
    优化算法用于记录中不只包括索引键值和记录的位置,还包括查询中要求的字段。这么做避免了需要2次读取记录。改进的
    filesort 算法做法大致如下: 1. 跟以前一样,读取匹配 WHERE 分句的记录。
    2.
    相对于每个记录,都记录了一个对应的;‘元组’信息信息,包括索引键值、记录位置、以及查询中所需要的所有字段。
  2. 根据索引键对‘元组’信息进行排序。 4.
    按序读取记录,不过是从已经排序过的‘元组’列表中读取记录,而非从数据表中再读取一次。
    使用改进后的 filesort
    算法相比原来的,‘元组’比‘对’需要占用更长的空间,它们很少正好适合放在排序缓冲中。因此,这就可能需要有更多的I/O操作,导致改进的算法更慢。为了避免使之变慢,这种优化方法只用于排序‘元组’中额外的字段的大小总和超过系统变量
    max_length_澳门新葡亰赌995577,for_sort_data 的情况。想要提高 ORDER BY
    的速度,首先要看MySQL能否使用索引而非额外的排序过程。如果不能使用索引,可以试着遵循以下策略:
    * 增加 sort_buffer_size 的值。 * 增加 read_rnd_buffer_size 的值。
    * 修改 tmpdir,让它指向一个有很多剩余空间的专用文件系统。 如果使用MySQL
    4.1或更新,这个选项允许有多个路径用循环的格式。各个路径之间在 Unix
    上用冒号分隔开来,在 Windows,NetWare以及OS/2
    上用分号。可以利用这个特性将负载平均分摊给几个目录。注意:这些路径必须是分布在不同物理磁盘上的目录,而非在同一个物理磁盘上的不同目录。