首页 > 技术文章 > 记优化数据库的经历

hanyouchun 2014-10-22 16:55 原文

一:针对where 条件 order by 字段 优化 (2014-10-22)

  问题:只要加上order by 速度就很慢

  介绍:

  一个文章表,大小有1.6G,表结构是

  id(主键递增)   nid(小说书id)  vid(小说章节id)  content(小说内容)  time(时间)

  业务要求:搜索出每本小说的前12个最新章节

  sql: 

   Select id,name,content From table where nid=1024 order by time desc limit 12
  优化经历:
  原本表中对nid这个字段加个索引,时间快了一点,但是只要使用order by就顿时慢了,所以就要想办法优化order by
  对这块的优化,最好是使用联合索引,针对nid和time
  ALTER TABLE table ADD INDEX nid_time_index(nid,time);
  速度明显上升,问题解决
二:针对联合查询join order by  limit优化(2014-10-23)
     问题:表中400w+数据,left join联合查询,如果加上order by 后,速度慢很多
     原始sql:
          select * from t_people p left join t_team t on p.team_id=t.id order by p.pname limit 10;
     优化:
          先搜索再limit出最少的数据,10条数据,再去联合查询,还可以继续在order by 的字段上添加索引并指定desc 或者 asc
           create  index  pnameindex  on  t_people (pname asc)
           select * from (select * from t_people p order by p.pname limit 10) p left join t_team t on p.team_id=t.id limit 10; 
     参考:http://blog.csdn.net/xiao__gui/article/details/8616224
总结:
    针对以上两个优化经历,可以得出结论是" mysql数据库是先搜索后排序 ",这样时间就消耗的多了,因此优化就是先筛选出需要的数据,再去排序
 
 三:
    1.谨慎使用TEXT/BLOB类型
      当列类型是TEXT或者BLOB时,我们应该特别注意,因为当选择的字段有 text/blob 类型的时候,无法创建内存表,只能创建硬盘临时表,而硬盘临时表的性能比内存表的性能差,所以如果非要使用TEXT/BLOB类型,应该单独建表,不要把TEXT/BLOB类型与核心属性混合在一张表中
   2.慎用子查询
      几乎所有子查询都可以改写为连接查询,有时候,连接查询的效率要比子查询高,所以把子查询改写成连接查询是一个不错的注意。如果一条使用子查询的select语句执行时间过长,那么就应该尝试把它改写为连接查询,看他是不是执行的更好。 
     select * from emp where ename in (select ename from ename);     
     select emp.* from emp inner join ename on emp.ename=ename.ename;
   3.在DISTINCT列上增加索引
   4.在group by后面增加order by null
    在使用group by分组查询时,默认分组后,还会排序,可能会降低速度。如果不需要排序,那么可以在group by后面增加order by null,这样可以避免分组后排序
 
 
 
 
 
 
 

推荐阅读