mysql优化案例分析
本文总结了一些工作常见的sql优化例子,虽然比较简单,但很实用,希望对大家有所帮助。sql优化一般分为两类,一类是sql本身的优化,如何走到合适 的索引,如何减少排序,减少逻辑读;另一类是sql本身没有优化余地,需要结合业务场景进行优化。即在满足业务需求的情况下对sql进行改造,已提高 sql执行速度,减少响应时间。
例子1:
SELECT ID FROM SENDLOG WHERE TO_DAYS(NOW())-TO_DAYS(GMT_CREATE) > 7;
问题:对索引列GMT_CREATE进行了运算,无法使用索引
SELECT * FROM SENDLOG where result = 1 and gmt_create > '2013-10-29 12:40:44' limit 2000;
问题:result列含有索引,但mysql执行计划没有用到。
分析:result类型为char,传递的值1为整型,数据类型不一致,导致没法用索引,对于时间类型gmt_create > '2013-10-29 12:40:44',可以直接使用。
优化后sql:
SELECT * FROM SENDLOG where result = '1' and gmt_create > '2013-10-29 12:40:44' limit 2000;
场景:获取某个卖家未读的消息。
select count(*) from mc_msg where receiver='sun098' and status='UNREAD' and title is not null;
问题:有时候db负载飙高,sql响应时间变慢。
分析:导致db负载飙高的原因是多个大卖家并发查询的时,cpu和逻辑读增加,load飙高。由于receiver,status已有索引,sql本身已经没有优化空间,了解业务后发现其实业务不需要精确值,如果大于99条,页面就直接显示为99+
优化后sql:
select count(*) from (select id from mc_msg where receiver='sun098' and status='UNREAD' and title is not null limit 100) a;
例子4:
场景:查看历史订单留言记录,未读留言的放在前面,已读的放在后面,并且按时间递减排序
select * from( select ID,GMT_CREATE,GMT_MODIFIED,SENDER_ALI_ID,RECEIVER_ALI_ID,UNREAD_COUNT,STATUS,LAST_MESSAGE_ID,RELATION_ID,SELLER_ADMIN_SEQ,IS_READ from message_relation_sender WHERE SENDER_ALI_ID = 119545671 and UNREAD_COUNT > 0 order by LAST_MESSAGE_ID desc) m union all select * from( select ID,GMT_CREATE,GMT_MODIFIED,SENDER_ALI_ID,RECEIVER_ALI_ID,UNREAD_COUNT,STATUS,LAST_MESSAGE_ID,RELATION_ID,SELLER_ADMIN_SEQ,IS_READ from message_relation_sender WHERE SENDER_ALI_ID = 119545671 and UNREAD_COUNT = 0 order by LAST_MESSAGE_ID desc) n limit 5000,15;
select ID,GMT_CREATE,GMT_MODIFIED,SENDER_ALI_ID,RECEIVER_ALI_ID,UNREAD_COUNT,STATUS,LAST_MESSAGE_ID,RELATION_ID,SELLER_ADMIN_SEQ,IS_READ from message_relation_sender where SENDER_ALI_ID = 119545671 order by is_read desc, LAST_MESSAGE_ID desc limit 5000,15
分页的优化写法:
</div>select t1.ID,GMT_CREATE,GMT_MODIFIED,SENDER_ALI_ID,RECEIVER_ALI_ID,UNREAD_COUNT,STATUS,LAST_MESSAGE_ID,RELATION_ID,SELLER_ADMIN_SEQ,IS_READ from message_relation_sender t1, ( select id from message_relation_sender where SENDER_ALI_ID = 119545671 order by is_read desc, LAST_MESSAGE_ID desc limit 5000,15 )t2 where t1.id = t2.id
来自:http://www.cnblogs.com/cchust/p/3444510.html