本文总结了一些工作常见的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访问Excel 失败的解决方法(错误号:80070005,8000401a)

    用asp.net把值写入Excel在本地测试通过,然后提交服务器后老是写入不成功 并提示错误: Retrieving the COM class factory for component with ...

  2. Android使用SAX解析XML(4)

    util.java文件如下: package com.hzhi.my_sax; import java.io.IOException; import java.io.InputStream; impo ...

  3. 【转】php中XML、XSLT的结合运用

    原文:http://blog.csdn.net/bjbs_270/article/details/140253   下面我要讲的是一个简单的从数据库中抽取数据,生成XML文档,使用XSLT转换成HTM ...

  4. 第 19 章 CSS 其他样式

    学习要点: 1.颜色和透明度 2.盒子阴影和轮廓 3.光标样式 主讲教师:李炎恢 本章主要探讨 HTML5 中 CSS 其他剩下几个常用的样式,包括颜色.透明度.盒子的阴影轮廓以及光标的样式. 一.颜 ...

  5. 第 16 章 CSS 盒模型[下]

    学习要点: 1.元素可见性 2.元素盒类型 3.元素的浮动 主讲教师:李炎恢 本章主要探讨 HTML5 中 CSS 盒模型,学习怎样了解元素的外观配置以及文档的整体布局. 一.元素可见性 使用 vis ...

  6. EffectiveJava——请不要在代码中使用原生态类型

    先看一个栗子,看看能不能找出来里面的错误: /** * 请不要在新代码中使用原生态类型 * @author weishiyao * */ public class Test { public stat ...

  7. CodeBlock

    CodeBlock官网是: http://www.codeblocks.org/ 选择Download the binary release: 根据自己电脑的情况选择想要的版本:(以博主电脑为例,wi ...

  8. 通过RODBC包操作mysql数据库

    MySQL是一种开放源代码的关系型数据库管理系统(RDBMS),MySQL数据库系统使用最常用的数据库管理语言--结构化查询语言(SQL)进行数据库管理.---百度百科 1. MySQL安装 官网下载 ...

  9. Java一步一步构建web系统 在IDEA下用Maven搭建多模块项目

    1.需求 做一个项目会有很多模块,主要是方便复用,通过各个模块之间聚合.模块也可以独立出来,如公用类库,也可以在做其它项目中使用.该文的实例会有两个模块:分别为dallin-web模块,dallin- ...

  10. linux使用rpm重装jdk

    1.卸载jdk #rpm -qa | grep gcj 如果输出没有内容,说明没有jdk,如果输出有内容,要把搜索到的文件卸载掉,命令为: #rpm -e --nodeps [上步操作输出的文件] 然 ...