本文总结了一些工作常见的sql优化例子,虽然比较简单,但很实用,希望对大家有所帮助。sql优化一般分为两类,一类是sql本身的优化,如何走到合适的索引,如何减少排序,减少逻辑读;另一类是sql本身没有优化余地,需要结合业务场景进行优化。即在满足业务需求的情况下对sql进行改造,已提高sql执行速度,减少响应时间。

例子1:

SELECT ID FROM SENDLOG WHERE TO_DAYS(NOW())-TO_DAYS(GMT_CREATE) > 7;

问题:对索引列GMT_CREATE进行了运算,无法使用索引

优化后sql:
select id from sendlog where gmt_create < now() - 7
 
例子2:

SELECT * FROM SENDLOG where result =  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;

例子3:

场景:获取某个卖家未读的消息。

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;
 
分析:
(1)unread_count表示未读的订单留言记录数目;
(2)第一个子查询获取未读留言记录,第二子查询获取已读留言记录;
(3)LAST_MESSAGE_ID 递增,最新的订单留言,LAST_MESSAGE_ID最大。
(4)limit 5000,15是分页查询
这里使用union all,主要特点在于union all 不对结果集排序,直接合并,达到了“未读留言的放在前面,已读的放在后面”的效果,但同时也造成了两次扫描索引的结果,每个子查询都需要排序;而且union all还会产生临时表,执行代价会更大。
 
优化:
这里看到unread_count实际值对这个查询没有实际意义,我们只需要区分已读和未读即可。由于sql本身已经没有优化余地,考虑对表结构进行修改,加一个字段is_read,表示已读和未读。is_read=2表示未读;is_read=1表示已读。通过组合索引(SENDER_ALI_ID,is_read, LAST_MESSAGE_ID),既可以完成过滤,还可以完成排序。
 
优化后sql:
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
 
第二次优化:
由于索引不包含所有的返回字段,因此需要回表,而mysql对于limit 5000,15的查询却需要返回5015次,这种无效的返回很影响查询效率。

分页的优化写法:

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
 
分析:由于id是主键,不需要回表,通过连接查询,最终只需要15次回表即可。

mysql优化案例分析的更多相关文章

  1. mysql优化案例

    MySQL优化案例 Mysql5.1大表分区效率测试 Mysql5.1大表分区效率测试MySQL | add at 2009-03-27 12:29:31 by PConline | view:60, ...

  2. MySQL死锁案例分析与解决方案

    MySQL死锁案例分析与解决方案 现象: 数据库查询: SQL语句分析:  mysql. 并发delete同一行记录,偶发死锁.   delete from x_table where id=?   ...

  3. MySQL优化 - 性能分析与查询优化(转)

    出处:  MySQL优化 - 性能分析与查询优化 优化应贯穿整个产品开发周期中,比如编写复杂SQL时查看执行计划,安装MySQL服务器时尽量合理配置(见过太多完全使用默认配置安装的情况),根据应用负载 ...

  4. MySQL的索引单表优化案例分析

    建表 建立本次优化案例中所需的数据库及数据表 CREATE DATABASE db0206; USE db0206; CREATE TABLE `db0206`.`article`( `id` INT ...

  5. SQL性能优化案例分析

    这段时间做一个SQL性能优化的案例分析, 整理了一下过往的案例,发现一个比较有意思的,拿出来给大家分享. 这个项目是我在项目开展2期的时候才加入的, 之前一期是个金融内部信息门户, 里面有个功能是收集 ...

  6. MySQL优化 - 性能分析与查询优化

    优化应贯穿整个产品开发周期中,比如编写复杂SQL时查看执行计划,安装MySQL服务器时尽量合理配置(见过太多完全使用默认配置安装的情况),根据应用负载选择合理的硬件配置等. 1.性能分析 性能分析包含 ...

  7. mysql优化:explain分析sql语句执行效率

    Explain命令在解决数据库性能上是第一推荐使用命令,大部分的性能问题可以通过此命令来简单的解决,Explain可以用来查看SQL语句的执行效 果,可以帮助选择更好的索引和优化查询语句,写出更好的优 ...

  8. mysql优化–explain分析sql语句执行效率

    Explain命令在解决数据库性能上是第一推荐使用命令,大部分的性能问题可以通过此命令来简单的解决,Explain可以用来查看SQL语句的执行效 果,可以帮助选择更好的索引和优化查询语句,写出更好的优 ...

  9. Mysql之案例分析(一)

    可见性分析 CREATE TABLE `t` ( `id` int(11) NOT NULL, `k` int(11) DEFAULT NULL, PRIMARY KEY (`id`) ) ENGIN ...

随机推荐

  1. Asp.net Mvc模块化开发系列(目录)

    模块化开发是非常重要的,模块化开发是个系统性问题,为此我觉得有必须要写一个系列的文章才能基本说的清楚 那又为什么要写一个目录呢? 其一.是对我昨天承诺写一个系列新的文章的回应 其二.是先写出一个大纲, ...

  2. 孙鑫MFC学习笔记:15多线程

    15 1.进程地址空间 2.线程 3.CreateThread创建一个线程 4.CloseHandle关闭线程句柄,要在不再使用线程句柄的时候关闭,递减线程引用计数 5.编辑框默认不支持多行,需要打开 ...

  3. Scalaz(20)-Monad: Validation-Applicative版本的Either

    scalaz还提供了个type class叫Validation.乍看起来跟\/没什么分别.实际上这个Validation是在\/的基础上增加了Applicative功能,就是实现了ap函数.通过Ap ...

  4. 修改thinkphp路由模式,去掉Home

    第一步:入口文件增加 define('BIND_MODULE', 'Home'); 第二步:修改config文件,我这里路由模式设置为2 效果展示:

  5. Java经典实例:在正则表达式中控制大小写

    默认是:区分大小写的: 传递标志参数:Pattern.CASE_INSENSITIVE,以说明匹配时忽略大小写:如果你的代码运行在不同的地区那么你应该再添加一个Pattern.UNICODE_CASE ...

  6. excel查看VBA代码快捷键

    公司现在的很多自动化代码生成使用excel VBA,本来这事跟自己一点关系打不着,不过计划年底切换中间件,这得导致部分代码结构调整,自己还得去调整测试,老忘掉这快捷键,特记录下,Alt + F11

  7. 当子查询碰上NULL

    情景: 现在有如图两个表,boy和girl,对应着Boy和Girl两个bean,有共同字段id.name,另外boy还有个外键grilfriend(指向girl的id) 现在要查询所有的Boy,如果有 ...

  8. css知多少(3)——样式来源与层叠规则

    上一节<css知多少(2)——学习css的思路>有几个人留言表示思路很好.继续期待,而且收到了9个赞,我还是比较欣慰的.没看过的朋友建议先去看看上一节. 这一节就开始实践上一节的思路! 1 ...

  9. 一款经典的jQuery slidizle 幻灯片

    jQuery广告幻灯片进度条,水平/左右切换,垂直/上下切换,自动播放,缩略图列表切换 在线实例 默认效果 水平/左右切换 垂直/上下切换 循环 自动播放 缩略图 进度条 回调函数 使用方法 < ...

  10. Strip JS – 低侵入,响应式的 Lightbox 效果

    Strip  是一个灯箱效果插件,显示的时候只会覆盖部分的页面,这使得侵扰程度较低,并留出了空间与页面上的大屏幕,同时给予小型移动设备上的经典灯箱体验.Strp JS 基于 jQuery 库实现,支持 ...