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

因为可能需要对数据库的记录进行重新排序。在这篇文章中,笔者就谈谈提高Order By语句查询效率的两个思路,以供大家参考。

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

498)this.width=498;" border=0>

 一、建议使用一个索引来满足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

(0)

相关推荐

  • MYSQL随机抽取查询 MySQL Order By Rand()效率问题

    要从tablename表中随机提取一条记录,大家一般的写法就是:SELECT * FROM tablename ORDER BY RAND() LIMIT 1. 但是,后来我查了一下MYSQL的官方手册,里面针对RAND()的提示大概意思就是,在ORDER BY从句里面不能使用RAND()函数,因为这样会导致数据列被多次扫描.但是在MYSQL 3.23版本中,仍然可以通过ORDER BY RAND()来实现随机. 但是真正测试一下才发现这样效率非常低.一个15万余条的库,查询5条数据,居然要8秒

  • MySql带OR关键字的多条件查询语句

    上篇文章给大家介绍了Mysql带And关键字的多条件查询语句,下面给大家介绍MySql带OR关键字的多条件查询语句,感兴趣的朋友可以一起学习. MySQL带OR关键字的多条件查询,与AND关键字不同,OR关键字,只要记录满足任意一个条件,就会被查询出来. SELECT * | {字段名1,字段名2,--} FROM 表名 WHERE 条件表达式1 OR 条件表达式2 [-- OR 条件表达式n]; 查询student表中,id字段值小于15,或者gender字段值为nv的学生姓名 可以看出,返回

  • MySQL查询优化:连接查询排序limit(join、order by、limit语句)介绍

    不知道有没有人碰到过这样恶心的问题:两张表连接查询并limit,SQL效率很高,但是加上order by以后,语句的执行时间变的巨长,效率巨低. 情况是这么一个情况:现在有两张表,team表和people表,每个people属于一个team,people中有个字段team_id. 下面给出建表语句: 复制代码 代码如下: create table t_team ( id int primary key, tname varchar(100) ); create table t_people (

  • 数据库查询排序使用随机排序结果示例(Oracle/MySQL/MS SQL Server)

    Oracle查询结果集,随机排序 复制代码 代码如下: select * from table1 order by dbms_random.value(); MySQL随机查询出一条记录: 复制代码 代码如下: -- 下面的查询语句效率高,不要使用 SELECT * FROM table1 ORDER BY rand() LIMIT 1 来查询 SELECT * FROM table1 WHERE id=(SELECT id FROM table1 ORDER BY rand() LIMIT 1

  • mysql仿oracle的decode效果查询

    以下代码在MYSQL中测试通过,MSSQL应该能跑通,未测试. 复制代码 代码如下: #创建表如下 create temporary table tmp (a int, b int ,c int); insert into tmp VALUES (1,10,1),(10,10,2),(10,100,2); #mysql执行 select sum(case when c = '1' then A else B end) from tmp #oracle执行 select sum(decode(c,

  • MySQL中使用or、in与union all在查询命令下的效率对比

    OR.in和union all 查询效率到底哪个快? 网上很多的声音都是说union all 快于 or.in,因为or.in会导致全表扫描,他们给出了很多的实例. 但真的union all真的快于or.in? EXPLAIN SELECT * from employees where employees.first_NAME ='Georgi' UNION ALL SELECT * from employees where employees.first_NAME ='Bezalel' 这条语

  • Oracle、MySQL和SqlServe三种数据库分页查询语句的区别介绍

    先来定义分页语句将要用到的几个参数: int currentPage ; //当前页 int pageRecord ; //每页显示记录数 以之前的ADDRESSBOOK数据表为例(每页显示10条记录): 一.SqlServe下载 分页语句 String sql = "select top "+pageRecord +" * from addressbook where id not in (select top "+(currentPage-)*pageRecor

  • Mysql联合查询UNION和Order by同时使用报错问题的解决办法

    因此,常常出现这样的错误 复制代码 代码如下: select * from [IND] where INDID>10unionselect * from [IND] where INDID<9 目前为止,还没有出现问 之后,也许有人会用到类似的查询 复制代码 代码如下: select * from [IND] where INDID>10 order by INDID descunionselect * from [IND] where INDID<9 order by INDID

  • oracle,mysql,SqlServer三种数据库的分页查询的实例

    MySql: MySQL数据库实现分页比较简单,提供了 LIMIT函数.一般只需要直接写到sql语句后面就行了.LIMIT子 句可以用来限制由SELECT语句返回过来的数据数量,它有一个或两个参数,如果给出两个参数, 第一个参数指定返回的第一行在所有数据中的位置,从0开始(注意不是1),第二个参数指定最多返回行数.例如:select * from table WHERE - LIMIT 10; #返回前10行select * from table WHERE - LIMIT 0,10; #返回前

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

    因为可能需要对数据库的记录进行重新排序.在这篇文章中,笔者就谈谈提高Order By语句查询效率的两个思路,以供大家参考. 在MySQL数据库中,Order by语句的使用频率是比较高的.但是众所周知,在使用这个语句时,往往会降低数据查询的性能.因为可能需要对数据库的记录进行重新排序.在这篇文章中,笔者就谈谈提高Order By语句查询效率的两个思路,以供大家参考. 498)this.width=498;" border=0> 一.建议使用一个索引来满足Order By子句. 在条件允许的

  • MySql中流程控制函数/统计函数/分组查询用法解析

    路漫漫其修远兮,吾将上下而求索,又到了周末,我继续带各位看官学习回顾Mysql知识. 上次说到了流程控制函数,那就从流程控制函数来继续学习吧! #五.流程控制函数 #1.if函数:if else的效果 IF(条件表达式,成立返回1,不成立返回2) #与Java三元运算相同 SELECT IF(10>5,'大','小'); SELECT last_name,commission_pct,IF(commission_pct IS NULL,'没奖金呵呵','有奖金嘻嘻') AS 备注 FROM em

  • MySQL中distinct和group by去重效率区别浅析

    目录 一.distinct 二.group by 三.distinct 和 group by 比较 总结 一.distinct distinct的作用 在mysql中,distinct关键字的主要作用就是对数据库表中一个或者多个字段重复的数据进行过滤,只返回其中的一条数据给用户,distinct只可以在select中使用 distinct的原理 distinct进行去重的主要原理是通过先对要进行去重的数据进行分组操作,然后从分组后的每组数据中去一条返回给客户端,在这个分组的过程可能会出现两种不同

  • 浅谈mysql中多表不关联查询的实现方法

    大家在使用MySQL查询时正常是直接一个表的查询,要不然也就是多表的关联查询,使用到了左联结(left join).右联结(right join).内联结(inner join).外联结(outer join).这种都是两个表之间有一定关联,也就是我们常常说的有一个外键对应关系,可以使用到 a.id = b.aId这种语句去写的关系了.这种是大家常常使用的,可是有时候我们会需要去同时查询两个或者是多个表的时候,这些表又是没有互相关联的,比如要查user表和user_history表中的某一些数据

  • 根据mysql慢日志监控SQL语句执行效率

    根据mysql慢日志监控SQL语句执行效率 启用MySQL的log-slow-queries(慢查询记录). 在Linux环境下先要找到my.cnf文件(一般在/etc/mysql/),然后可能会发现该文件修改后无法保存,原因是你没有相应的权限,可以从属性中看到该文件的所有者是root,这时要先以root的身份打开它: sudo nautilus /etc/mysql 接着再打开my.cnf文件然后找到[mysqld]标签在下面加上: log-slow-queries=/path/slow.lo

  • PostgreSQL数据库中如何保证LIKE语句的效率(推荐)

    在任何数据库中使用LIKE语句往往都是令人头疼的一件事,因为不少用户发现LIKE语句效率极低,查看执行计划后发现原来没有走索引,那么在Postgresql数据中LIKE语句的执行效率又是怎样的呢?我们又该如何提高LIKE语句的执行效率呢?   实验环境 数据库环境: PostgreSQL 12.3  X86_64 创建虚拟环境: postgres=# create database testdb01 owner highgo; CREATE DATABASE postgres=# \c test

  • mysql中使用instr进行模糊查询方法介绍

    在mysql中使用内部函数instr,可代替传统的like方式查询,并且速度更快. instr 函数,第一个参数是字段,第二个参数是要查询的串,返回串的位置,第一个是1,如果没找到就是0. 例如,查询字段name中带"军"的名字,传统的方法是: select name from 用户表 where name like `%军%'; 用instr的方法: select name from 用户表 where instr('name','军'); 或: select name from 用

  • 图文详解Mysql中如何查看Sql语句的执行时间

    目录 一.初始SQL准备 二.Mysql查看Sql语句的执行时间 三.不同查询的执行时间 总结 Mysql中如何查看Sql语句的执行时间 一.初始SQL准备 初始化表 -- 用户表 create table t_users( id int primary key auto_increment, -- 用户名 username varchar(20), -- 密码 password varchar(20), -- 真实姓名 real_name varchar(50), -- 性别 1表示男 0表示

  • MySQL中的SQL标准语句详解

    目录 前言 对数据库的操作 对表的操作 表的创建 表的插入 表的修改 表的删除 表的查询 条件查询 前言 例如MySQL中的LIMIT语句就是MySQL独有的方言,其它数据库都不支持!当然,Oracle或SQL Server都有自己的方言. 语法要求: SQL语句可以单行或多行书写,以分号结尾: 可以用空格和缩进来来增强语句的可读性: 关键字不区别大小写,建议使用大写: 对数据库的操作 #语法: CREATE DATABASE [IF NOT EXISTS] 数据库名 [DEFAULT CHAR

  • MySQL中union和join语句使用区别的辨析教程

    union和join是需要联合多张表时常见的关联词,具体概念我就不说了,想知道上网查就行,因为我也记不准确. 先说差别:union对两张表的操作是合并数据条数,等于是纵向的,要求是两张表字段必须是相同的(Schema of both sides of union should match.).也就是说如果A表中有三条数据,B表中有两条数据,那么A union B就会有五条数据.说明一下union 和union all的差别,对于union如果存在相同的数据记录会被合并,而union all不会合

随机推荐