mysql中使用order by 和limit查询变慢解决办法_MySQL, Oracle及数据库讨论区_Weblogic技术|Tuxedo技术|中间件技术|Oracle论坛|JAVA论坛|Linux/Unix技术|hadoop论坛_联动北方技术论坛  
网站首页 | 关于我们 | 服务中心 | 经验交流 | 公司荣誉 | 成功案例 | 合作伙伴 | 联系我们 |
联动北方-国内领先的云技术服务提供商
»  游客             当前位置:  论坛首页 »  自由讨论区 »  MySQL, Oracle及数据库讨论区 »
总帖数
1
每页帖数
101/1页1
返回列表
0
发起投票  发起投票 发新帖子
查看: 2339 | 回复: 0   主题: mysql中使用order by 和limit查询变慢解决办法        下一篇 
gunrose
注册用户
等级:新兵
经验:36
发帖:79
精华:0
注册:2011-7-21
状态:离线
发送短消息息给gunrose 加好友    发送短消息息给gunrose 发消息
发表于: IP:您无权察看 2014-12-29 17:09:56 | [全部帖] [楼主帖] 楼主

本文章来给大家介绍一篇关于mysql中使用order by 和limit查询变慢解决办法,因为在mysql分页利用limit来操作,同时排序也需要使用了order by ,所以经常会两者同是使用到,但是如果数据量大的话就会碰到查询很慢很慢,下面我来给大家介绍解决办法。

1.显示行 0 - 9 (10 总计, 查询花费 32.4894 秒)  
2.SQL 查询: SELECT *  
3.FROM tables  
4.WHERE m_id  
5.IN ( 50, 49 )  
6.ORDER BY id DESC  
7.LIMIT 10  
显示行 0 - 9 (10 总计, 查询花费 32.4894 秒)
SQL 查询: SELECT *

 FROM tables
WHERE m_id
IN ( 50, 49 )
ORDER BY id DESC
LIMIT 10


1.显示行 0 - 9 (10 总计, 查询花费 0.0497 秒)  
2.SQL 查询: SELECT *  
3.FROM tables  
4.WHERE m_id  
5.IN ( 50, 49 )  
6.LIMIT 10   
显示行 0 - 9 (10 总计, 查询花费 0.0497 秒)
SQL 查询: SELECT *

 FROM tables
WHERE m_id
IN ( 50, 49 )
LIMIT 10


1.显示行 0 - 29 (1,333 总计, 查询花费 0.0068 秒)  
2.SQL 查询: SELECT *  
3.FROM tables  
4.WHERE m_id  
5.IN ( 50, 49 )  
6.ORDER BY id DESC  
7. 
显示行 0 - 29 (1,333 总计, 查询花费 0.0068 秒)
SQL 查询: SELECT *

 FROM tables
WHERE m_id
IN ( 50, 49 )
ORDER BY id DESC


1.显示行 0 - 29 (1,333 总计, 查询花费 0.12秒)  
2.SQL 查询: SELECT *  
3.FROM tables  
4.WHERE m_id  
5.IN ( 50, 49 )  
6.ORDER BY m_id, id DESC  
7. 
显示行 0 - 29 (1,333 总计, 查询花费 0.12秒)
SQL 查询: SELECT *

 FROM tables
WHERE m_id
IN ( 50, 49 )
ORDER BY m_id, id DESC


1.显示行 0 - 29 (1,333 总计, 查询花费 0.0068 秒)  
2.SQL 查询: SELECT *  
3.FROM tables  
4.FORCE INDEX ( m_id )     //强制索引  
5.WHERE m_id  
6.IN ( 50, 49 )  
7.ORDER BY id DESC  
8. 

上面的办法如果数据量上千万级也是会很慢的,有可能查询一次到10秒或更长,

优化limit和offset

MySQL的limit工作原理就是先读取n条记录,然后抛弃前n条,读m条想要的,所以n越大,性能会越差。

优化前SQL: SELECT * FROM member ORDER BY last_active LIMIT 50,5
优化后SQL: SELECT * FROM member INNER JOIN (SELECT member_id FROM member ORDER BY last_active LIMIT

 50, 5) USING (member_id)


分别在于,优化前的SQL需要更多I/O浪费,因为先读索引,再读数据,然后抛弃无需的行。而优化后的SQL(子查询

那条)只读索引(Cover index)就可以了,然后通过member_id读取需要的列。

对mysql服务器优化也可以提升性能了

1、只返回需要的数据

返回数据到客户端至少需要数据库提取数据、网络传输数据、客户端接收数据以及客户端处理数据等环节,如果返

回不需要的数据,就会增加服务器、网络和客户端的无效劳动,其害处是显而易见的,避免这类事件需要注意:

A、横向来看,不要写SELECT *的语句,而是选择你需要的字段。

B、纵向来看,合理写WHERE子句,不要写没有WHERE的SQL语句。

C、注意SELECT INTO后的WHERE子句,因为SELECT INTO把数据插入到临时表,这个过程会锁定一些系统表,如果这

个WHERE子句返回的数据过多或者速度太慢,会造成系统表长期锁定,诸塞其他进程。

D、对于聚合查询,可以用HAVING子句进一步限定返回的行。

2、尽量少做重复的工作

这一点和上一点的目的是一样的,就是尽量减少无效工作,但是这一点的侧重点在客户端程序,需要注意的如下:

A、控制同一语句的多次执行,特别是一些基础数据的多次执行是很多程序员很少注意的。

B、减少多次的数据转换,也许需要数据转换是设计的问题,但是减少次数是程序员可以做到的。

C、杜绝不必要的子查询和连接表,子查询在执行计划一般解释成外连接,多余的连接表带来额外的开销。

D、合并对同一表同一条件的多次UPDATE,比如

UPDATE EMPLOYEE SET FNAME=’HAIWER’ WHERE EMP_ID=’ VPA30890F’
UPDATE EMPLOYEE SET LNAME=’YANG’ WHERE EMP_ID=’ VPA30890F’
UPDATE EMPLOYEE SET FNAME=’HAIWER’,LNAME=’YANG’
WHERE EMP_ID=’ VPA30890F’


E、UPDATE操作不要拆成DELETE操作+INSERT操作的形式,虽然功能相同,但是性能差别是很大的。

F、不要写一些没有意义的查询,比如: SELECT * FROM EMPLOYEE WHERE 1=2

3、注意事务和锁

事务是数据库应用中和重要的工具,它有原子性、一致性、隔离性、持久性这四个属性,很多操作我们都需要利用

事务来保证数据的正确性。在使用事务中我们需要做到尽量避免死锁、尽量减少阻塞。具体以下方面需要特别注意



A、事务操作过程要尽量小,能拆分的事务要拆分开来。

B、事务操作过程不应该有交互,因为交互等待的时候,事务并未结束,可能锁定了很多资源。

C、事务操作过程要按同一顺序访问对象。

D、提高事务中每个语句的效率,利用索引和其他方法提高每个语句的效率可以有效地减少整个事务的执行时间。

E、尽量不要指定锁类型和索引,SQL SERVER允许我们自己指定语句使用的锁类型和索引,但是一般情况下,SQL

SERVER优化器选择的锁类型和索引是在当前数据量和查询条件下是最优的,我们指定的可能只是在目前情况下更有

,但是数据量和数据分布在将来是会变化的。

F、查询时可以用较低的隔离级别,特别是报表查询的时候,可以选择最低的隔离级别

--转自 北京联动北方科技有限公司




赞(0)    操作        顶端 
总帖数
1
每页帖数
101/1页1
返回列表
发新帖子
请输入验证码: 点击刷新验证码
您需要登录后才可以回帖 登录 | 注册
技术讨论