`
亚当爱上java
  • 浏览: 711944 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

MySQL如何优化ORDER BY

阅读更多
7.2.9 MySQL 如何优化 ORDER BY

在一些情况下,MySQL可以直接使用索引来满足一个 ORDER BY 或 GROUP BY 子句而无需做额外的排序。尽管 ORDER BY 不是和索引的顺序准确匹配,索引还是可以被用到,只要不用的索引部分和所有的额外的 ORDER BY 字段在 WHERE 子句中都被包括了。下列的几个查询都会使用索引来解决 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,尽管它会使用索引来找到记录来匹配 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 上用分号(';')。可以利用这个特性将负载平均分摊给几个目录。注意:这些路径必须是分布在不同物理磁盘上的目录,而非在同一个物理磁盘上的不同目录。


默认情况下,MySQL也会对所有的 GROUP BY col1, col2, ... 查询做排序,跟 ORDER BY col1, col2, ... 查询一样。如果显式地包含一个有同样字段列表的 ORDER BY 分句,MySQL优化它的时候并不会损失速度,因为排序总是会发生。如果一个查询中包括 GROUP BY,但是想要避免对结果排序的开销,可以通过使用 ORDER BY NULL 来取消排序。例如:


INSERT INTO foo

SELECT a, COUNT(*) FROM bar GROUP BY a ORDER BY NULL;


7.2.10 MySQL 如何优化 LIMIT

在一些情况下,MySQL在碰到一个使用 LIMIT row_count 但没使用 HAVING 的查询时会做不同的处理:


* 如果只是用 LIMIT 来取得很少的一些记录, MySQL 有时会使用索引,但是更通常的情况是做一个全表扫描。

* 如果 LIMIT row_count 和 ORDER BY 一起使用,则MySQL在找到 row_count 条记录后就会停止排序了,而非对整个表进行排序。

* 当 LIMIT row_count 和 DISTINCT 一起联合起来时,MySQL在找到 row_count 条唯一记录后就不再搜索了。

* 在某些情况下, GROUP BY 可以通过按照顺序读取索引键来实现(或者在索引键上做排序)并且计算累计信息直到索引键改变了。在这种情况下,LIMIT row_count 不会计算任何非必须的 GROUP BY 值。

* As soon as MySQL has sent the required number of rows to the client, it aborts the query unless you are using SQL_CALC_FOUND_ROWS.

* 一旦MySQL将请求的记录全数发送给客户端后,它就中止查询除非使用了 SQL_CALC_FOUND_ROWS。

* LIMIT 0 总是返回一个空的结果集。这对于检查查询或者取得结果字段的类型非常有用。

* 当服务器使用临时表来处理查询,则 LIMIT row_count 可以用来计算需要多少空间。


7.2.11 如何避免全表扫描

如果MySQL需要做一次全表扫描来处理查询时,在 EXPLAIN 的结果中 type 字段的值是 ALL。在以下几种条件下,MySQL就会做全表扫描:


* 数据表是在太小了,做一次全表扫描比做索引键的查找来得快多了。当表的记录总数小于10且记录长度比较短时通常这么做。

* 没有合适用于 ON 或 WHERE 分句的索引字段。

* 让索引字段和常量值比较,MySQL已经计算(基于索引树)到常量覆盖了数据表的很大部分,因此做全表扫描应该会来得更快。详情请看"7.2.4 How MySQL Optimizes WHERE Clauses"。

* 通过其他字段使用了一个基数很小(很多记录匹配索引键值)的索引键。这种情况下,MySQL认为使用索引键需要大量查找,还不如全表扫描来得更快。
分享到:
评论

相关推荐

    BLDC无刷直流电机Simulink双闭环调速系统仿真设计及应用

    内容概要:本文详细介绍了BLDC无刷直流电机在Matlab Simulink环境下的仿真设计,特别是转速和电流双闭环调速系统的实现方法。首先解释了为什么需要进行BLDC电机的仿真设计及其优势,接着简述了Simulink仿真环境的特点和功能。重点在于双闭环调速系统的设计,包括转速外环的PID控制器和电流内环的PWM技术的具体实现方式。最后展示了仿真过程与结果分析,附带简单的代码片段供参考。 适合人群:从事电机控制系统研究的技术人员、高校师生及相关领域的研究人员。 使用场景及目标:适用于希望深入了解BLDC电机控制原理和技术细节的人群,旨在帮助他们掌握基于Simulink平台的BLDC电机建模与仿真的技能。 其他说明:文中提供的代码片段仅为示意,具体实现还需参照完整文档和资料进一步学习。

    实训商业源码-匹饲养养殖场网站模板-毕业设计.zip

    实训商业源码-匹饲养养殖场网站模板-毕业设计.zip

    西门子S7-200SMART恒压供水系统:一对一变频调节与PID控制的全自动解决方案

    内容概要:本文介绍了基于西门子S7-200SMART PLC的恒压供水系统设计方案。该系统采用一对一变频调节,四台主泵与一台辅泵配置,通过PID调节实现自动投切电机和频率调整。系统配有详细的电气图纸和IO点号表,确保安装、调试和维护的便利性。同时,系统集成了西门子触摸屏,提供友好的人机交互界面,便于用户操作和监控。实际工程应用表明,该系统运行稳定,节能效果显著。 适合人群:从事自动化控制系统设计、安装和维护的技术人员,尤其是熟悉西门子PLC和变频器的应用工程师。 使用场景及目标:适用于工业和民用建筑中的恒压供水项目,旨在提高供水系统的稳定性、可靠性和节能效率。 其他说明:文中附有简化的PLC代码示例,展示了如何根据压力变化调整电机状态和频率,为读者提供了实用的参考。

    STM32学习第一课-工程建立

    STM32学习第一课-工程建立

    人力资源分析数据集.rar

    该数据集为结构化人力资源分析数据,涵盖员工全生命周期管理指标,包含员工编号、年龄、部门、职位、教育背景、薪资结构(时薪/日薪/月薪)、绩效评级、培训记录及离职原因等核心字段。数据维度覆盖员工满意度(工作环境、职业发展、工作生活平衡)、任职稳定性(工龄、晋升年限、通勤距离)以及组织效能(部门效能、项目完成量)三大方向,涉及招聘效率、薪酬公平性、人才流失预警等典型人力资源管理场景。 数据采用CSV/XLSX标准化格式存储,包含超过30项可量化指标,包含定量数据(工作时长、薪资数值)与定性指标(满意度评分、离职类型)的混合数据类型。适用于社会科学研究中的人力资本分析、组织行为学模型构建,支持通过Python/Pandas、Tableau等工具开展描述性统计、相关性分析和预测建模。数据集已进行匿名化处理,符合GDPR等数据隐私保护规范,包含完整的数据字典和元数据说明文件。

    中国省市区旅游景点数据.rar

    中国省市区旅游景点数据是以行政区划为单位的全国性旅游资源结构化数据集,覆盖31个省级行政区域(含直辖市、自治区),包含2443条景点信息。数据集包含11个核心字段:城市、景点名称、星级(含4A/5A等级评定)、评分(0-5分游客满意度)、门票价格、销量(门票或游客量)、省/市/区归属、地理坐标(经纬度定位)、简介(含历史文化背景及特色)、是否免费标识、具体地址。数据来源于公开采集的景区官方信息及旅游平台统计,可支持多维分析应用,包括全国景点地理空间分布、游客行为偏好、景区价格体系比较、热门景区客流量预测等研究方向。 该数据集采用Excel格式存储,便于使用Pandas、R等工具进行数据清洗与统计分析,并可通过Pyecharts、Tableau等工具实现可视化呈现。典型应用场景包括:通过坐标字段生成省级热力图,结合销量和评分分析区域旅游经济贡献度,或基于星级和价格字段研究景区评级与消费水平关联性。数据内容已应用于社科领域研究,如《中国A级旅游景区空间分结构研究》等文献,为区域经济规划、文旅政策制定提供基础数据支撑。数据集包含完整字段说明文档,适用于旅游管理、人文地理、区域经济学等学科量化研究。

    论文模板-2022 多个分类随机海量高清壁纸系统源码-实训商业源码.zip

    论文模板-2022 多个分类随机海量高清壁纸系统源码-实训商业源码.zip

    实训商业源码-大气的影视公司网站源码-毕业设计.zip

    实训商业源码-大气的影视公司网站源码-毕业设计.zip

    基于MATLAB的车牌定位算法设计.doc

    基于MATLAB的车牌定位算法设计.doc

    基于Matlab Simulink的双馈风力发电机电网模型及其外扰波形变化研究

    内容概要:本文主要介绍了利用Matlab Simulink平台搭建双馈风力发电机(DFIG)在电网中的模型,并对其在外扰条件下的转矩、功率和电压波形变化进行了深入的研究。首先,文章阐述了双馈风力发电机的基本原理和结构,接着详细描述了如何在Simulink环境中构建DFIG模型并设置相关参数。随后,通过对不同类型的外部干扰进行模拟实验,分析了这些干扰对DFIG各项电气参数的具体影响,如转矩波动、有功无功功率变化以及电压稳定性的改变。最后,作者提供了详尽的技术文档和支持材料来帮助读者进一步理解DFIG的工作机制及其在电力系统中的表现。 适合人群:从事风能发电领域的研究人员和技术人员,特别是那些希望深入了解双馈风力发电机特性和行为的专业人士。 使用场景及目标:适用于想要探索DFIG在复杂电网环境下动态响应特征的研究项目;也可用于指导工程实践中针对DFIG系统的优化设计与故障诊断。 其他说明:文中不仅包含了理论分析,还有大量的实验数据支持,确保研究成果的真实可靠。同时提供的参考资料有助于初学者快速掌握相关知识。

    基因工程(一)基因的结构和基因工程的基本工具.doc

    基因工程(一)基因的结构和基因工程的基本工具.doc

    实训商业源码-App软件落地页网站源码-毕业设计.zip

    实训商业源码-App软件落地页网站源码-毕业设计.zip

    基于遗传算法优化SVM的多输入单输出预测模型及其可视化分析

    内容概要:本文详细介绍了如何利用遗传算法(GA)优化支持向量机(SVM)进行多输入单输出的拟合预测建模。首先,通过sklearn生成模拟数据集并进行预处理,然后采用DEAP库实现遗传算法寻找SVM的最佳超参数(如C和gamma)。接着,使用最佳参数训练SVM模型并对测试集进行预测,最终通过多种图表形式展示预测结果与真实值之间的关系以及误差分布情况,并给出多个性能评估指标。 适合人群:对机器学习尤其是SVM和支持向量回归有一定了解的数据科学家、研究人员和技术爱好者。 使用场景及目标:适用于希望提高SVM模型预测精度的研究人员或从业者,在面对复杂非线性数据时能够自动寻优超参数,减少人工试错成本,提升模型泛化能力。 其他说明:文中提供了完整的代码实现步骤,从数据准备到模型训练再到结果可视化,帮助读者全面掌握整个流程。此外还提到了一些注意事项,比如遗传算法可能存在局部最优解的问题,提醒使用者灵活调整相关参数设置。

    嵌入usb控制器的51系列单片机ez-usb的应用.doc

    嵌入usb控制器的51系列单片机ez-usb的应用.doc

    基于空间矢量控制的永磁同步电机转速系统设计与仿真:MATLAB Simulink平台实现

    内容概要:本文详细介绍了基于空间矢量控制(SVM)的永磁同步电机(PMSM)状态反馈控制转速系统的设计与仿真。首先,文章阐述了永磁同步电机的基本模型及其组成部分,包括电机本体、驱动电路和控制电路。接着,重点讨论了空间矢量控制策略,这是一种能根据电机实时状态调整输入电压幅度和相位的高效控制方法。然后,深入讲解了状态反馈控制机制,即通过实时采集电机的状态信息并计算实际运行状态,与期望状态进行比较,进而得出控制信号以调整电机运行。最后,在MATLAB/Simulink平台上进行了系统建模与仿真,展示了电机在不同负载和输入条件下的性能变化,并通过调整参数和控制策略找到了最优设计方案。 适合人群:电气工程专业学生、电机控制系统研究人员和技术人员。 使用场景及目标:适用于需要深入了解永磁同步电机控制原理的研究人员和技术人员,旨在帮助他们掌握空间矢量控制和状态反馈控制的方法,提升电机运行效率和寿命。 其他说明:文中还提供了一段简短的Simulink模型代码示例,便于读者理解和实践。

    实训商业源码-蓝色营销型五金配件网站源码-毕业设计.zip

    实训商业源码-蓝色营销型五金配件网站源码-毕业设计.zip

    实训商业源码-教育培训机构网站-毕业设计.zip

    实训商业源码-教育培训机构网站-毕业设计.zip

    第8章S7-200通信及网络.ppt

    第8章S7-200通信及网络.ppt

    python相关学习资源,python

    python

    实训商业源码-HTML5响应式健身俱乐部类pbootcms网站模板-毕业设计.zip

    实训商业源码-HTML5响应式健身俱乐部类pbootcms网站模板-毕业设计.zip

Global site tag (gtag.js) - Google Analytics