mysql中提高Order by语句查询效率的两个思路分析

所属分类: 数据库 / Mysql 阅读数: 1418
收藏 0 赞 0 分享
因为可能需要对数据库的记录进行重新排序。在这篇文章中,笔者就谈谈提高Order By语句查询效率的两个思路,以供大家参考。

在MySQL数据库中,Order by语句的使用频率是比较高的。但是众所周知,在使用这个语句时,往往会降低数据查询的性能。因为可能需要对数据库的记录进行重新排序。在这篇文章中,笔者就谈谈提高Order By语句查询效率的两个思路,以供大家参考。

 

 一、建议使用一个索引来满足Order By子句。

在条件允许的情况下,笔者建议最好使用一个索引来满足Order By子句。如此的话,就可以避免额外的排序工作。这里笔者需要强调的一点是及时Order By子句不确切匹配索引,但是只要Where子句中所有未使用的索引部分和所有额外的 Order by子句中的列为常数,此时就可以使用索引。具体的来说,推荐如下的查询语句。

1、select * from ad_user where is_active='Y' order by value;

在这条查询语句中,使用了两个列。在Where查询语句中,查询表中活动的记录。此时使用的是一个常数的条件。而在Order By子句中,则根据Value列的值来进行排序。如果在表设计中,为这个字段设置一个索引。此时使用这条语句来进行查询,则查询结果就不需要进行额外的排序工作,从而可以提高数据的查询效率。

这也就是说,如果Where条件语句与Order By条件语句一起使用,如果需要通过一个索引来提高查询效率的话,那么就必须满足一个条件,及where条件语句中所使用的参数值是常数,而不是变量。如果使用变量的话,这个方法就不奏效了。

2、注意有些情况下不能够使用索引来提高Order By语句的查询性能。

这里需要注意的是,并不是任何情况下都能够通过使用索引来提高Order Byz子句的查询效率。如对不同的关键字使用这个语句、混合使用ASC模式和DESC模式、用于查询条件的关键字与Order By语句中所使用的关键字不同、对关键字的非连续元素使用Order By子句、在同一条语句中使用不同的Order BY 和Group BY表达式、使用的表索引的类型不能够按顺序来保存行等情况,就无法通过使用索引来解决Order By语句的排序问题。此时就需要另想他法。如可以重新调整表结构或者查询语句,以满足使用这个特性的特定条件。

其实这里就遇到一个均衡的问题。如在查询时,Where条件语句中往往使用的是一个变量,这主要是为了提高语句的灵活性。这个变量接受前端用户传递过来的参数。此时如果用户同时有排序的需求,根据上面介绍的规则,就无法使用索引来提高查询的效率。此时作为开发人员,就需要评估,需要语句的灵活性还是需要查询的性能。通常情况下,对于记录量比较大的查询,同时其查询的格式比较固定,如大容量的月报与年报,此时就会倾向于查询语句的性能。而对于记录量比较少的查询,如日报表,或者使用频率比较高的查询语句,此时会更加的倾向于查询的灵活性。作为开发人员,现在需要关注的就是根据用户实际的情况,来选择合适的解决方式。

通常情况下,为了避免使用Order By语句导致的查询速度变慢的问题,先是需要考虑使用索引来解决问题。如果不能够通过索引来解决问题,那么可以通过缓存在一定程度来缓解。如可以增加soft_buffer_size变量的大小、根据实际情况调整Read_buffer_size变量的大小、更改tmpdir目录将其指向具有大量空闲空间的专用文件系统等等。有时候管理员可以使用这个特性将负载均匀分布到多个目录中去。

二、使用Explain关键字来确认是否可以通过索引来解决Order BY速度问题。

如果用户无法确定是否可以通过索引来提高Order By语句的查询效率,那么就可以凭借Explain关键字来帮助关键员进行判断。如可以通过使用explain select * from ad_user where is_active='Y' order by value(即在常规的查询语句前面加上一个explain关键字),用来判断是否可以使用索引来提高查询的效率。判断的方法是:如果这个查询语句中,有一个using filesort这个字段,那么就非常的抱歉,无法通过使用索引来提高这个语句的查询效率。反之,没有这个字段,则说明可以通过索引来提高查询效率。

这里需要说明的是,通常情况下文件排序优化不仅仅可以用于记录排序关键字和行的位置,并且还会记录查询所需要的列。如此的话,就可以避免多次读取行的信息。为了让大家更加明白其中的道理笔者简单说明一下这工作的过程。通常情况下,文件排序优化包括四 个步骤。第一步读取与Where条件语句所匹配的行信息;第二步对于每个行、记录构成排序关键字和行位置的一系列值,并且记录查询所需要的列;第三步根据排序关键字排序元祖;第四步按排序的顺序检索行,不过此时是直接从排序的元祖读取所需要的列(使用的是第三个步骤中的结果),而不会重新访问表中的数据。显然使用文件排序优化的思路,可以避免重复访问表,从而提高查询的效率。

原文链接:http://publish.itpub.net/a2011/0225/1160/000001160766.shtml

更多精彩内容其他人还在看

mysql found_row()使用详解

在参考手册中对found_rows函数的描述是: it is desirable to know how many rows the statement would have returned without the LIMIT. 也就是说,它返回值是如果SQL语句没有加LI
收藏 0 赞 0 分享

很全面的MySQL处理重复数据代码

这篇文章主要为大家详细介绍了MySQL处理重复数据的实现代码,如何防止数据表出现重复数据及如何删除数据表中的重复数据,感兴趣的小伙伴们可以参考一下
收藏 0 赞 0 分享

图文详解Ubuntu下安装配置Mysql教程

这篇文章主要以图文结合的方式详细为大家介绍了Ubuntu安装配置Mysql的实现步骤,感兴趣的小伙伴们可以参考一下
收藏 0 赞 0 分享

Ubuntu下mysql安装和操作图文教程

这篇文章主要为大家详细分享了Ubuntu下mysql安装和操作图文教程,喜欢的朋友可以参考一下
收藏 0 赞 0 分享

Linux/UNIX和Window平台上安装Mysql

这篇文章主要为大家详细介绍了Linux/UNIX和Window两个系统上采用命令安装Mysql的方法,感兴趣的小伙伴们可以参考一下
收藏 0 赞 0 分享

忘记MySQL的root密码该怎么办

忘记密码总是一件令人头疼的事情,当我们忘记了MySQL的root密码该怎么办?本文给出解决方法,感兴趣的小伙伴们可以参考一下
收藏 0 赞 0 分享

Mysql存储引擎MyISAM的常见问题(表损坏、无法访问、磁盘空间不足)

这篇文章主要介绍了Mysql存储引擎MyISAM的常见问题,针对表损坏、无法访问、磁盘空间不足等问题进行解决,感兴趣的小伙伴们可以参考一下
收藏 0 赞 0 分享

VS2013连接MySQL5.6成功案例一枚

这篇文章主要为大家分享了VS2013连接MySQL5.6成功案例一枚,很有实用性,感兴趣的小伙伴们可以参考一下
收藏 0 赞 0 分享

Windows下mysql修改root密码的4种方法

这篇文章主要为大家详细介绍了windows下mysql修改root密码的4种方法,大家可以根据的自己的实际情况进行选择,感兴趣的小伙伴们可以参考一下
收藏 0 赞 0 分享

mysql Sort aborted: Out of sort memory, consider increasing server sort buffer size的解决方法

这篇文章主要介绍了mysql Sort aborted: Out of sort memory, consider increasing server sort buffer size的解决方法,需要的朋友可以参考下
收藏 0 赞 0 分享
查看更多