【MYSQL优化之道摘抄】mysql常见的SQL优化方法
前言
无论对于开发人员、运维人员或者测试人员,数据库的优化都是绕不开的话题。而在数据库的优化中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优化方法相关推荐
- 常见的SQL优化方法
总结一些常见的SQL优化方式 对查询进行优化,应尽量避免全表扫描,首先应考虑在where及order by涉及到的列上建立索引. 应该尽量避免在where子句中使用!=或<>操作符,否则将 ...
- 阿里P8架构师谈:MySQL数据库的索引原理、与慢SQL优化的5大原则
MySQL凭借着出色的性能.低廉的成本.丰富的资源,已经成为绝大多数互联网公司的首选关系型数据库.虽然性能出色,但所谓"好马配好鞍",如何能够更好的使用它,已经成为开发工程师的必修 ...
- mysql 批量导入sql_MySQL高效导入多个.sql文件方法详解
MySQL有多种方法导入多个.sql文件(里面是sql语句),常用的有两个命令:mysql和source. 但是这两个命令的导入效率差别很大,具体请看最后的比较. (还有sqlimport和LOAD ...
- 12 | 存储优化(上):常见的数据存储方法有哪些?
通过专栏前面我讲的 I/O 优化基础知识,相信你肯定了解了文件系统和磁盘的一些机制,以及不同 I/O 方式的使用场景以及优缺点,并且可以掌握如何在线上监控 I/O 操作. 万丈高楼平地起,在理解并掌握 ...
- 高性能MySQL(3th)(第六章 sql优化) —— 06 查询优化器的工作
一 优化器在MySQL架构中的位置: 二 先看逻辑上的作用 一言以蔽之:找到最好的执行计划. 三 静态优化和动态优化 这个和一般的编译器优化的区别差不多,静态优化即语法上的转换,替换常量等等,动态优化 ...
- mysql不同的类的个数_Mysql数据库-SQL优化-统计某种类型的个数
有时我们想统计某种类型有多少个,会用这个SQL.全表扫描之余,还要filesort,耗时1.34秒. mysql> select country,count(*) from t1 group b ...
- 高性能MySQL(3th)(第六章 sql优化) —— 01 减少冗余数据
一 查询冗余的条数 如实际前台只需要TOP10,但是查询时使用 LIMIT 100. 解决方案:使用需要的大小限制.e.g. LIMIT 10,或者至多 LIMIT 20. 二 查询冗余的的列 避免使 ...
- 如何用js语句给mysql添加内容_在js里写SQL的方法
在日新月异的前端领域中,前端工程师能做的事情越来越多,自从nodejs出现后,前端越来越有革了传统后端命的趋势,本文就再补一刀,详细解读如何在js代码中执行标准的SQL语句 为什么要在js里写SQL? ...
- arcgis select by attributes一次选多个_优化体系--记一次生产数据库sql优化过程--组合索引...
概述 最近比较有空,所以看了一些问题sql,顺便优化一下,做个简单记录. 问题sql SQL(c212jfrj1m0fg) 在采样期平均单次执行逻辑读为 106205.83, 其最新执行计划涉及 2 ...
最新文章
- 转android项目开发 工作日志 2011.10.8--onConfigurationChanged屏幕改变事件
- 谷歌旗下Waymo开启数据集虚拟挑战赛
- 统计学习II.7 广义线性模型1 指数分布族
- html中能比较两个小数吗,javascript如何判断数值是否为小数?
- VIPKID上云 解决多云Web统一安全防护问题
- services.xml应该放在项目的哪里_新轮胎应该放在前轮还是后轮?
- Atitit.列表页面and条件查询的实现最佳实践(1)------设置查询条件and提交查询and返回json数据
- 如何在虚拟机安装windows server 2003
- 未来计算机技术的发展趋势有哪些,浅谈计算机技术的发展趋势
- 2021年T电梯修理考试题及T电梯修理模拟考试题
- 迷你迅雷 vs. QQ旋风
- QuartusII9.0--项目文件的新建
- erp系统有什么用?中小企业实施erp软件的好处有哪些
- 街头篮球 服务器维护,新闻中心-自由篮球-FreeStyle2-官方网站-世纪天成游戏-街头篮球 正统续作...
- 如何下载风云卫星数据?
- 在线购物系统 问题描述、词汇表、领域类图
- antd4.x [antd: Switch] `value` is not a valid prop, do you mean `checked`? 解决办法
- 适用选择并遮住抠人物头发丝
- Access-Control-Allow-Origin 解决方法
- Mendix敏捷开发零基础学习《二》-进阶(Microflow微流、表单验证、运算符、条件判断、数据嵌套、触发器、Debug问题跟踪、版本管理)
热门文章
- 解决:华为Mate20 从拍照进入图片浏览模式怎么返回拍照 ?【华为脑残的设计师啊!】
- mysql 添加索引 创建索引
- 卅年史诗!地球上出现过的CPU完全收藏 - (6-9) 确立x86地位创造商业奇迹的CPU系列——80x86系列
- C++ primer 第9章顺序容器 思维导图
- 机器学习基础-关于matplotlib的动态图显示操作
- php composer failed to open file: phar://composer.phar/bin........问题解决
- spark debug远程调试
- 手写体识别代码_【玩转腾讯云】使用API快速构建文字识别小工具之唐诗识别
- 发票管理之发票识别技术的应用
- Web端点餐系统(HTML5 + CSS3 + JS(jQuery))