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

所属分类: 数据库 / Mysql 阅读数: 1521
收藏 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中按照多字段排序及问题解决

这篇文章主要介绍了MySQL中按照多字段排序及问题解决的方法,非常的实用,有需要的小伙伴可以参考下。
收藏 0 赞 0 分享

MySQL外键使用详解

两天有人问mysql中如何加外键,今天抽时间总结一下。mysql中MyISAM和InnoDB存储引擎都支持外键(foreign key),但是MyISAM只能支持语法,却不能实际使用。
收藏 0 赞 0 分享

Mysql中LAST_INSERT_ID()的函数使用详解

从名字可以看出,LAST_INSERT_ID即为最后插入的ID值,有了这个实用的函数,我们可以实现很多问题,下面我们就来深入探讨下。
收藏 0 赞 0 分享

MySql insert插入操作的3个小技巧分享

这篇文章主要介绍了MySql insert插入操作的3个小技巧分享,本文讲解了插入的数据来源自其他表、插入时排除(忽略)重复记录、插入时遇到重复记录做更新操作三个小技巧,需要的朋友可以参考下
收藏 0 赞 0 分享

mysql修改自增长主键int类型为char类型示例

这篇文章主要介绍了mysql修改自增长主键int类型为char类型示例,需要的朋友可以参考下
收藏 0 赞 0 分享

Windows下使用Cygwin编译MySQL客户端

这篇文章主要介绍了Windows下使用Cygwin编译MySQL客户端,本文详细的讲解了编译过程,需要的朋友可以参考下
收藏 0 赞 0 分享

MySQL数据库优化推荐的编译安装参数小结

这篇文章主要介绍了MySQL数据库优化推荐的编译安装参数小结,需要的朋友可以参考下
收藏 0 赞 0 分享

MySQL之Field‘***’doesn’t have a default value错误解决办法

这篇文章主要介绍了MySQL之Field‘***’doesn’t have a default value错误解决办法,需要的朋友可以参考下
收藏 0 赞 0 分享

php连接MySQL的两种方式对比

这篇文章主要介绍了php连接MySQL的两种方式对比,一种是原生的链接方式另外一种是PDO方式,附上示例,推荐给大家,有需要的小伙伴可以参考下
收藏 0 赞 0 分享

Mysql InnoDB删除数据后释放磁盘空间的方法

这篇文章主要介绍了Mysql InnoDB删除数据后释放磁盘空间的方法,Innodb数据库对于已经删除的数据只是标记为删除,并不真正释放所占用的磁盘空间,这就导致InnoDB数据库文件不断增长,本文就讲解释放磁盘空间的方法,需要的朋友可以参考下
收藏 0 赞 0 分享
查看更多