• 售前

  • 售后

热门帖子
入门百科

mysql织梦索引优化之MySQL Order By索引优化

[复制链接]
伊索谗言 显示全部楼层 发表于 2021-8-16 16:57:04 |阅读模式 打印 上一主题 下一主题
在一些情况下,MySQL可以直接利用索引来满意一个ORDER BY 或GROUP 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 中的字段都不满是来自第一个非常数的表中(也就是说,在EXPLAIN 分析的效果中的第一个表的毗连范例不是const)。
* 利用了不同的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(7)个地域的块生存在另一个暂时文件中。重复这个操纵,直到全部在第一个文件的块都放到第二个文件了。
6. 重复以上操纵,直到剩余的块数量小于MERGEBUFF2 (15)。
7. 在最后一次多重归并时,只有纪录的指针(排序索引键的最后部分)写到效果文件中去。
8. 通过读取效果文件中的纪录指针来按序读取纪录。想要优化这个操纵,MySQL将纪录指针读取放到一个大的块里,而且利用它来按序读取纪录,将纪录放到缓冲中。缓冲的巨细由体系变量read_rnd_buffer_size 的值而定。这个步调的代码在源文件`sql/records.cc' 中。
这个逼近算法的一个问题是,读取了2次纪录:一次是估算WHERE 分句时,第二次是排序时。只管第一次都成功读取纪录了(例如,做了一次全表扫描),第二次是随机的读取(索引键已经排好序了,但是纪录并没有)。在MySQL 4.1 及更新版本中,filesort 优化算法用于纪录中不只包括索引键值和纪录的位置,还包括查询中要求的字段。这么做克制了必要2次读取纪录。改进的filesort 算法做法大致如下:
1. 跟从前一样,读取匹配WHERE 分句的纪录。
2. 相对于每个纪录,都纪录了一个对应的;‘元组’信息信息,包括索引键值、纪录位置、以及查询中所必要的全部字段。
3. 根据索引键对‘元组’信息进行排序。
4. 按序读取纪录,不外是从已经排序过的‘元组’列表中读取纪录,而非从数据表中再读取一次。
利用改进后的filesort 算法相比原来的,‘元组’比‘对’必要占用更长的空间,它们很少正好适合放在排序缓冲中(缓冲的巨细是由sort_buffer_size 的值决定的)。因此,这就大概必要有更多的I/O操纵,导致改进的算法更慢。为了克制使之变慢,这种优化方法只用于排序‘元组’中额外的字段的巨细总和超过体系变量max_length_for_sort_data 的情况(这个变量的值设置太高的一个表象就是高磁盘负载低CPU负载)。想要提高ORDER BY 的速度,起主要看MySQL能否利用索引而非额外的排序过程。假如不能利用索引,可以试着遵循以下策略:
* 增长sort_buffer_size 的值。
* 增长read_rnd_buffer_size 的值。
* 修改tmpdir,让它指向一个有许多剩余空间的专用文件体系。
假如利用MySQL 4.1或更新,这个选项答应有多个路径用循环的格式。各个路径之间在Unix 上用冒号(':')分隔开来,在Windows,NetWare以及OS/2 上用分号(';')。可以利用这个特性将负载均匀分摊给几个目次。注意:这些路径必须是分布在不同物理磁盘上的目次,而非在同一个物理磁盘上的不同目次

帖子地址: 

回复

使用道具 举报

分享
推广
火星云矿 | 预约S19Pro,享500抵1000!
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

草根技术分享(草根吧)是全球知名中文IT技术交流平台,创建于2021年,包含原创博客、精品问答、职业培训、技术社区、资源下载等产品服务,提供原创、优质、完整内容的专业IT技术开发社区。
  • 官方手机版

  • 微信公众号

  • 商务合作