设为首页 加入收藏

TOP

sql limit 优化方法
2011-06-12 21:46:43 来源: 作者: 【 】 浏览:763次 评论:0

通常情况下,limit关键字可以接受一个或者两个数字参数。需要注意的是,这个参数必须是一个整数常量。如果用户给定两个参数,则第一个参数表示第一个返回记录行的偏移量,第二个参数则表示返回记录行的最大数据。另外需要提醒的是,初始记录行的偏移量是0,而不是1。不少用户会在这里犯错误。

  虽然使用了limit语句来限制返回的记录数,从而可以提高应用程序的工作效率。但是其也会给系统的性能带来一些负面影响。如可能会导致全表扫描等等。为此笔者给出一些limit关键字的优化的建议,以供大家参考。

  建议一:灵活使用limit 0子句

  根据limit关键字的定义,如果参数为0的话,则其返回的是空记录。这看起来好像没有多少的意义。其实不然。在实际工作中,灵活使用这个0参数,能够给我们带来很大的收获。

  如现在数据库教程工程师想要确认一下某个查询语句的有效性,如果直接运行这个查询语句,需要等待其返回的记录。如果涉及的纪录数量比较多,或者运算逻辑比较复杂,那么需要等到比较长的时间。此时就可以在select查询语句中,使用limit 0子句。只要查询语句没有语法上的错误,这就可以让数据库快速的返回一个空集合。从而帮助数据库设计人员迅速的判断查询语句的有效性。另外这个空集和中还会返回某个表的各个字段的数据类型。即通过这个limit 0子句还可以查询某个表的表结构。

  可见灵活应用limir 0子句,确实能够给我们带来不小的收益。不过需要注意的是,在某些特定的场合下,这个子句可能不会奏效。如通常情况下,在monitor工作环境中不支持这个limit 0子句。此时结果只会显示empty set,而不是我们所需要的结果。

  建议二:limit与group by结合使用

  group by关键字主要用来对数据进行分类汇总。不过在分类汇总之前,往往需要对数据先进性排序。而limit语句用来指定显示的结果数量时,往往也需要涉及到纪录的分类汇总与排序的问题。如现在一个学校成绩管理系统中,需要对学生的总分进行排序。即先对学生各科成绩进行汇总,然后显示其排名为前50的纪录。此时就需要同时用到group by子句和limit子句。其实从这个案例中我们也可以看出,这两个子句相互依赖的特性。正是因为这种特性(经常相互结合使用),为此结合group by子句可以提高limit的查询效率。

  这主要是因为两者如果一起使用的话,limit关键字将不会再重复计算任何不必要的group by的值。换句话说,在某些情况下,group by子句能够通过顺序来读取键或者在键上做排序来解决分类汇总时的排序问题,然后再计算摘要直到关键字的值的改变为止。如此的话,两个子句所需要做的一些共同性的工作,只要做一次即可。这就可以从另外一次角度用来提高应用系统的性能。相比先做一个视图对数据进行分类汇总的运算,再使用一个查询语句来抽取特定数量的记录,效率就要高一点。因为后者是将两个子句分开来使用,就无法享受到结合使用所体现的优势。

  建议三:使用sql_calc_found_rows来提高子句的灵活性

  默认情况下,limit子句返回用户所指定的记录行数。只要数据库已经发送了用户所需要的行数,则数据库系统会放弃剩余的查询。即上面这个学生成绩的案例中,如果用户只需要返回总分成绩排名前50的学生,则数据库只返回50条记录,然后终止查询作业。

  但是在某些特定的情况下,用户可能仍然需要继续后续的查询呢?如用户出了查询某些特定的记录,还需要知道总的记录数量,此时该如何处理?如现在用户需要知道排名前50的学生信息,同时需要知道总分在500分以上的总人数。此时单独使用limit子句可能无法满足用户的需求,因为其只关心前面50条记录。如果要实现这个需求的话,往往需要结合sql_calc_found_rows关键字。

  这个关键字的主要用途就是能够在查询时为数据库管理员事先准备好符合where条件语句的记录数目。然后用户只要在随后执行一条select found_rows语句之后,就可以获得符合条件的记录总数。不过需要注意的是,使用这个关键字会带来一定的副作用。即带有这个关键字的查询语句,是无法使用数据缓存的。故在某些情况下会降低数据查询的性能。故一般情况下,这个关键字只用于where条件语句比较复杂的情况。当然这只是一个出于性能考虑的建议,而并不是技术上的限制。即即使where条件语句不复杂,也可以使用这个关键字,不会出现语法上的错误。只是其在性能上并不是很理想。

  建议四:与distinct关键字共同使用时的特殊现象

  distinct关键字主要用来过滤重复的记录。而limit关键字则主要用来指定记录所返回的行数。如果这两个关键字共同使用时,会出现什么样的情况呢?如果从字面意思去理解,数据库会返回指定的不重复的记录数。如limit的参数为50,则数据库返回50条不重复的记录数。然后后续的查询就会停止。如果查询的记录中有重复记录,则数据库查询的实际数量往往要比limit关键字所指定的数量要多。

  在实际工作中,这条语句的作用还是很大的。如现在有一张员工考勤信息的表格。现在数据库管理员需要统计缺勤次数排名前20的员工人数。此时为了防止有重复的记录,就可以在查询语句中加一个distinct关键字,用来过滤重复的记录数。从而可以避免采用多个查询语句来完成这个需求。

  建议五:limit与索引之间的关系

  如果数据库管理员决定使用limit子句来指定需要显示的记录数,那么最好能够最大限度的使用索引,以避免全表扫描,提高工作效率。即当数据库选择做完整的表扫描时,可以在某些情况下使用索引。

  如现在数据库管理员决定将limit子句与order by子句一起使用。数据库一旦找到了排序结果的第一个rowcount行,则系统将会结束排序,而并不会对整个表进行排序。如果单独使用order by子句的话,则会对整个表进行排序。虽然如此,但是排序必定要浪费一定的时间。此时数据库管理员如果决定使用索引,则可以在很大程度上提高这个查询的效率。

看一个老外写的

sometimes we may not want to retrieve all the records that satsify the critera specified in where or having clauses.

in mysql教程, this is accomplished using the limit keyword. the syntax for limit is as follows:

[sql statement 1]
limit [n]

where [n] is the number of records to be returned. please note that the order by clause is usually included in the sql statement. without the order by clause, the results we get would be dependent on what the database default is.

for example, we may wish to show the two highest sales amounts in table store_information

table store_information

store_namesalesdate
los angeles$1500jan-05-1999
san diego$250jan-07-1999
san francisco$300jan-08-1999
boston$700jan-08-1999

we key in,

select store_name, sales, date
from store_information
order by sales desc
limit 2;


result:

store_namesalesdate
los angeles$1500jan-05-1999
boston$700jan-08-1999

您看到此篇文章时的感受是:
Tags: 责任编辑:administrator
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到QQ空间
分享到: 
上一篇sql 主表的一条记录对应附表的多.. 下一篇mysql thread_cache_size优化方法

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容:

相关栏目

最新文章

图片主题

热门文章

推荐文章

相关文章

广告位