前言

无论对于开发人员、运维人员或者测试人员,数据库的优化都是绕不开的话题。而在数据库的优化中SQL的优化又是最为关键的一项。再牛逼的服务器硬件也扛不住百万次的oracle硬解析,再快的SSD硬盘和raid,碰到千万级数据的全表扫描也一样会趴窝。这就是SQL优化的重要性,但是也恰恰是最容易被忽视的。SQL优化虽然深邃,但是入门不难,这里整理了以前的一些MYSQL的优化笔记,遵循这些优化原则的话,至少能保证数据库不会被慢SQL跑死。

关于优化的一些原则

  • 所有的优化,其本质都是在时间、空间、成本、可容忍度四个要素之间取得的一种平衡。
  • 优化没有绝对的银弹,不存在100分效果的优化策略。总是要做取舍。
  • 任何数据库的优化,都要从SQL的优化开始
  • 80%的慢SQL问题都是因为:1、没有索引;2、索引不合理;3、有索引但是实际执行却没有走索引
  • ORACLE一定要注意避免硬解析;MYSQL的硬解析足够快,但也要注意使用绑定变量。

关于MYSQL中的索引优化原则:

  • 联合索引遵循最左侧原则,将where使用最频繁的列放在最左侧
  • 联合索引的效率一般高于单列索引
  • 字段使用函数,将不能使用索引
  • 无引号导致全表扫描,无法使用索引
  • 当取出的数据量超过表中数据的20%,优化器就不会使用索引,而是全表扫描
  • 涉及到order by gourp by的语句,将where条件和order group的字段作为联合索引,排序方法要一致

MYSQL优化实践

not in子查询优化

在生产环境中应该尽量避免子查询,可以用left join表连接代替。
优化前:

select SQL_NO_CACHE count(*) from test1 where id not in (select id from test2);
not exists:
select SQL_NO_CACHE ount(*) from test1 where not exists (select * from test2 where test2.id=test1.id);

优化后:

select SQL_NO_CACHE count(*) from test1 left join test2 on test1.id=test2.id where test2.id is not null;

通过子查询删除已查询的记录时会报错:1093,例如

mysql > delete from t where id in (select id from t where id <5);

执行后,会报错error 1093,you can`t specify taret table ‘t’ fo update in from clause,需要修改为:

mysql > delete from t where id in (select * from (select id from t where id < 5) tmp);

继续优化为表连接方式:

mysql> delete t from t join (select id from t where id < 5) tmp on t.id=tmp.id

模式匹配 like '%xxx%'优化

mysql里 like 'xxx%'可以用到索引,但是like '%xxx%'会走全表扫描。解决方法:覆盖索引,也就是select的字段正好就是索引
优化前:

select count(*) from artist where name like '%Queen%'

优化后:

select count(*) from artist a join (select aritst_id from artist where name like '%Queen%') b  on a.artist_id = b.artist_id

其中aritst_id是主键索引

limit 分页优化

优化前:

mysql > select sql_no_cache * frm test1 order by id limit 99999,10

SQL相当于执行了全表扫描,要先定位到99999,再扫描出后10行。优化的方法其实很简单,首先通过id定位到99999行,然后再执行limit:

select sql_no_cache * frm test1 where id > 99999 order by id limit 10;

关于这种优化一定注意和代码的协同,大多数开发人员会在代码中把d > 99999作为入参传递给JDBC,但是也见过直接在底层的DAO层写死了固定条件,这样的话排查问题的时候容易被忽视,从而导致不必要的工作量。

count(*)优化

老生常谈的优化。我倾向于对于count(*),首先通过缓存优化,如果要求强一致性,可以考虑做二级缓存自动更新数据。这里只考虑SQL层面的优化方法。
通过辅助索引的方式,这种方式其实是增加了一个永远为TRUE的where条件,但是执行效率却是天上地下。同时这个方法需要注意索引的额外开销。

-- 优化前
select count(*) from up_user;
-- 优化后
select count(*) from up_user where sid >=0;

通过distinct的方式,但是有局限性,有可能distinct本身就会成为一个瓶颈

--优化前:
select count(disinct(k)) from sbtest;
-- 优化后:
select count(*) from (select distinck k from sbtest) tmp;

类似count sum的函数尽量不要在主库上执行,生产环境用的是InnoDB引擎,不想MyISAM引擎(OLAP)内置了计数器

OR 条件优化

使用OR的SQL语句都不会走索引。可以用union all合并or两端的结果集,这种做法还一个好处是他属于相同语义转换。优化前后的返回结果一定是一致的。

-- 优化前:
select * from user where name='d' or age=41;
-- 优化后:
select * from user where name='d' union all select * from user where age=41;

高效解决主键冲突

mysql中主键冲突带来的性能损耗容易被忽视。其实处理也简单,on DUPLICATE KEY UPDATE即可,但是要注意这个是MYSQL才有的语法,如果涉及到多数据库支持的话,需要在代码上考虑对数据库类型的兼容性

insert into up_relation(ownerid,contactidisbuddy,ischatfriend,isblacklist) values (value1,value2,1,0,0)
on DUPLICATE KEY UPDATE isBuddy=1,IschatFriend=0

避免不要必要的排序

在count,sum等聚合操作中去掉无用的order by

-- 优化前:
select * from  (
select a.id,a.title,a.content,b.log_time,b.name from a,b where a.content like 'rc_%' and a.id = b.id order by a.title desc
) as rs_table limit 0,30

像这种子查询里的order by就完全没有意义,但是我经常在生产环境的监控中看到这种SQL,一方面是有开发同学的粗心大意和复制粘贴大法,另外也有DAO框架生成SQL不合理的原因。

-- 优化后:
select a.id,a.title,a.content,b.log_time,b.name from a join b on a.id = b.id and a.content like 'rc_%' order by a.title desc liit 0,30

用where 字句替换having子句

having只会在检索出所有记录后才对结果集进行过滤,一般情况下,having子句中的条件用于对一些集合函数的比较,如count等,除此以外,都应该写在where子句中

【MYSQL优化之道摘抄】mysql常见的SQL优化方法相关推荐

  1. 常见的SQL优化方法

    总结一些常见的SQL优化方式 对查询进行优化,应尽量避免全表扫描,首先应考虑在where及order by涉及到的列上建立索引. 应该尽量避免在where子句中使用!=或<>操作符,否则将 ...

  2. 阿里P8架构师谈:MySQL数据库的索引原理、与慢SQL优化的5大原则

    MySQL凭借着出色的性能.低廉的成本.丰富的资源,已经成为绝大多数互联网公司的首选关系型数据库.虽然性能出色,但所谓"好马配好鞍",如何能够更好的使用它,已经成为开发工程师的必修 ...

  3. mysql 批量导入sql_MySQL高效导入多个.sql文件方法详解

    MySQL有多种方法导入多个.sql文件(里面是sql语句),常用的有两个命令:mysql和source. 但是这两个命令的导入效率差别很大,具体请看最后的比较. (还有sqlimport和LOAD ...

  4. 12 | 存储优化(上):常见的数据存储方法有哪些?

    通过专栏前面我讲的 I/O 优化基础知识,相信你肯定了解了文件系统和磁盘的一些机制,以及不同 I/O 方式的使用场景以及优缺点,并且可以掌握如何在线上监控 I/O 操作. 万丈高楼平地起,在理解并掌握 ...

  5. 高性能MySQL(3th)(第六章 sql优化) —— 06 查询优化器的工作

    一 优化器在MySQL架构中的位置: 二 先看逻辑上的作用 一言以蔽之:找到最好的执行计划. 三 静态优化和动态优化 这个和一般的编译器优化的区别差不多,静态优化即语法上的转换,替换常量等等,动态优化 ...

  6. mysql不同的类的个数_Mysql数据库-SQL优化-统计某种类型的个数

    有时我们想统计某种类型有多少个,会用这个SQL.全表扫描之余,还要filesort,耗时1.34秒. mysql> select country,count(*) from t1 group b ...

  7. 高性能MySQL(3th)(第六章 sql优化) —— 01 减少冗余数据

    一 查询冗余的条数 如实际前台只需要TOP10,但是查询时使用 LIMIT 100. 解决方案:使用需要的大小限制.e.g. LIMIT 10,或者至多 LIMIT 20. 二 查询冗余的的列 避免使 ...

  8. 如何用js语句给mysql添加内容_在js里写SQL的方法

    在日新月异的前端领域中,前端工程师能做的事情越来越多,自从nodejs出现后,前端越来越有革了传统后端命的趋势,本文就再补一刀,详细解读如何在js代码中执行标准的SQL语句 为什么要在js里写SQL? ...

  9. arcgis select by attributes一次选多个_优化体系--记一次生产数据库sql优化过程--组合索引...

    概述 最近比较有空,所以看了一些问题sql,顺便优化一下,做个简单记录. 问题sql SQL(c212jfrj1m0fg) 在采样期平均单次执行逻辑读为 106205.83, 其最新执行计划涉及 2 ...

最新文章

  1. 转android项目开发 工作日志 2011.10.8--onConfigurationChanged屏幕改变事件
  2. 谷歌旗下Waymo开启数据集虚拟挑战赛
  3. 统计学习II.7 广义线性模型1 指数分布族
  4. html中能比较两个小数吗,javascript如何判断数值是否为小数?
  5. VIPKID上云 解决多云Web统一安全防护问题
  6. services.xml应该放在项目的哪里_新轮胎应该放在前轮还是后轮?
  7. Atitit.列表页面and条件查询的实现最佳实践(1)------设置查询条件and提交查询and返回json数据
  8. 如何在虚拟机安装windows server 2003
  9. 未来计算机技术的发展趋势有哪些,浅谈计算机技术的发展趋势
  10. 2021年T电梯修理考试题及T电梯修理模拟考试题
  11. 迷你迅雷 vs. QQ旋风
  12. QuartusII9.0--项目文件的新建
  13. erp系统有什么用?中小企业实施erp软件的好处有哪些
  14. 街头篮球 服务器维护,新闻中心-自由篮球-FreeStyle2-官方网站-世纪天成游戏-街头篮球 正统续作...
  15. 如何下载风云卫星数据?
  16. 在线购物系统 问题描述、词汇表、领域类图
  17. antd4.x [antd: Switch] `value` is not a valid prop, do you mean `checked`? 解决办法
  18. 适用选择并遮住抠人物头发丝
  19. Access-Control-Allow-Origin 解决方法
  20. Mendix敏捷开发零基础学习《二》-进阶(Microflow微流、表单验证、运算符、条件判断、数据嵌套、触发器、Debug问题跟踪、版本管理)

热门文章

  1. 解决:华为Mate20 从拍照进入图片浏览模式怎么返回拍照 ?【华为脑残的设计师啊!】
  2. mysql 添加索引 创建索引
  3. 卅年史诗!地球上出现过的CPU完全收藏 - (6-9) 确立x86地位创造商业奇迹的CPU系列——80x86系列
  4. C++ primer 第9章顺序容器 思维导图
  5. 机器学习基础-关于matplotlib的动态图显示操作
  6. php composer failed to open file: phar://composer.phar/bin........问题解决
  7. spark debug远程调试
  8. 手写体识别代码_【玩转腾讯云】使用API快速构建文字识别小工具之唐诗识别
  9. 发票管理之发票识别技术的应用
  10. Web端点餐系统(HTML5 + CSS3 + JS(jQuery))