MySQL写出高效SQL
mysql设计标准
事务处理标准
索引使用标准
约束设计
sql语句标准
怎么写出高效SQL
清晰无误的了知业务需求
满足业务需求,不做无用功
知道表数据量和索引基本情况
知道完成SQL需要扫描的数据量级
SQL执行计划OK?SQL性能达到要求?
调整索引和SQL,优化SQL
IN子查询容易导致问题,禁止使用,需改成join
选择正确的驱动表:关键的第一步
错误使用Left Join
left join的表在where中出现,如
Table1 left join Table2 on Table1.C1=Table2.c1
where Table2.column1=XXX
实际上已经变成了inner join
Leftjoin会限制join顺序,而且where条件只能在join后过滤,影响性能
group by常见处理
利用index实现group by,避免使用临时表
group by是否必要?
提升group by性能的一些方法
--group by col1,col2 order by null/order by col1,col2
order by常见处理
利用索引来实现排序功能?
排序字段是否在驱动表上?
order by的几种优化方法
--using index/using filesort(两次扫描/一次扫描(max_length_for_sort_data/query))
set optimizer_trace='enabled=on';
set @@global.show_compatibility_56=ON;#5.7`performance_schema`.session_status
select varable_value into @a from `performance_schema`.session_status where variable_name='Innodb_rows_read';
#select city,name,age from t where city='chengdu' order by limit 1000;
select * from zabbix.events order by eventid limit 10
select * from information_schema.OPTIMIZER_TRACE;
select varable_value into @b from `performance_schema`.session_status where variable_name='Innodb_rows_read';
select @b-@a; #扫描的行数
SET optimizer_trace="enabled=off";
MySQL的排序优化
应尽可能避免排序或者尽可能避免对大量数据进行排序。如果需要排序的数据量小于排序缓冲区,MySQL使用内存进行“快速排序”操作
如果内存不够排序,那么MySQL会先将数据分块,对每个独立的块使用“快速排序”进行排序,并将各个块的排序结果存放在磁盘上,然后将各个排序的块进行合并,最后返回排序结果
单次传输排序(新版),一次读取出所有需要的或SQL查询指定的列,然后根据排序列,排序,直接返回排序后的结果。顺序I/O,缺点:如果列多,额外占用空间
在关联查询的时候如果需要排序,MySQL会分两种情况来处理这样的文件排序。如果ORDER BY子句的所有列都来自关联的第一个表
那么MySQL在关联处理第一个表时就进行文件排序。如果是这样那么在MySQL的EXPLAIN结果中可以看到Extra字段会有Using filesort。
除此之外的所有情况,MySQL都会将关联的结果存放在一个临时表中,然后在所有的关联都结束后,再进行文件排序。这种情况下Extra字段可以看到Using temporary;Using filesort。
如果查询中有LIMIT的话,LIMIT也会在排序之后应用,所以即使需要返回较少的数据,临时表和需要排序的数据量仍然会非常大
分页SQL优化
分页SQL可能包含order by,group by和多表join等操作,可以利用前面的优化手段
后台分页取数SQL可以用cursor替换,分批fetch;使用分页SQL多次取,性能差,数据一致性没保证
并发设置
并发不是越大越好,设置满足要求的最小并发数
高并发时MySQL处理能力会因为锁竞争、上下文切换等问题而下降
测出系统处理能力和并发数的曲线关系,知道系统性能拐点位置
子查询分类
Scalar Subquery
在select子句中标量子查询只能返回一个值
标量子查询可以分成depend和independ,independ子查询只需查询一次,depeng子查询需外
部查询返回的每条记录执行一次
在where子句中的标量子查询
= 和 in的区别
使用row(...)函数进行多列比较的问题
Nested Subquery
在from子句中的子查询
关联字段要有索引
主要形式有:in,not in,exists,not exitsts
标准版,转化成DEPENDENT SUBQUERY,即外部查询先执行,再执行子查询
多个Nested Subquery子查询时,一般按在查询出现先后次序,后出现的先执行
Mariadb版本可以转化成inline view,再join
Inline View
出现在from子句中的子查询
考虑join次序,查询条件能否推进Inline View (merge)
inline view作为驱动表?
inline view产生临时表?
inline view产生的临时表支持索引?
STRAIGHT_JOIN」强制连接顺序
-sql规范:
--禁用 select *,禁止dml,select语句缺少where
--禁止任何对where字段的计算,函数等操作DATE_FORMAT(gmt_create,'%Y%m%d%H%i%s')='2018061522300'
--jon的关联字段 数据类型一致,要有索引
--group by,order by 最好都能选择驱动表的列或者只选择一个表上的列
--不要使用 count(列名)或 count(常量)来替代 count(*)
--使用 ISNULL()来判断是否为 NULL 值
----
1、所有的InnoDB表都设计一个无业务用途的自增列做主键,对于绝大多数场景都是如此,真正纯只读用InnoDB表的并不多,真如此的话还不如用TokuDB来得划算;
2、字段长度满足需求前提下,尽可能选择长度小的。此外,字段属性尽量都加上NOT NULL约束,可一定程度提高性能;
3、尽可能不使用TEXT/BLOB类型,确实需要的话,建议拆分到子表中,不要和主表放在一起,避免SELECT * 的时候读性能太差。
4、读取数据时,只选取所需要的列,不要每次都SELECT *,避免产生严重的随机读问题,尤其是读到一些TEXT/BLOB列;
5、对一个VARCHAR(N)列创建索引时,通常取其50%(甚至更小)左右长度创建前缀索引就足以满足80%以上的查询需求了,没必要创建整列的全长度索引;
6、通常情况下,子查询的性能比较差,建议改造成JOIN写法;
7、多表联接查询时,关联字段类型尽量一致,并且都要有索引;
8、多表连接查询时,把结果集小的表(注意,这里是指过滤后的结果集,不一定是全表数据量小的)作为驱动表;
9、多表联接并且有排序时,排序字段必须是驱动表里的,否则排序列无法用到索引;
10、多用复合索引,少用多个独立索引,尤其是一些基数(Cardinality)太小(比如说,该列的唯一值总数少于255)的列就不要创建独立索引了;
11、类似分页功能的SQL,建议先用主键关联,然后返回结果集,效率会高很多;
关于MySQL的管理维护的其他建议有:
1、通常地,单表物理大小不超过10GB,单表行数不超过1亿条,行平均长度不超过8KB,如果机器性能足够,这些数据量MySQL是完全能处理的过来的,不用担心性能问题,这么建议主要是考虑ONLINE DDL的代价较高;
2、不用太担心mysqld进程占用太多内存,只要不发生OOM kill和用到大量的SWAP都还好;
3、在以往,单机上跑多实例的目的是能最大化利用计算资源,如果单实例已经能耗尽大部分计算资源的话,就没必要再跑多实例了;
4、定期使用pt-duplicate-key-checker检查并删除重复的索引。定期使用pt-index-usage工具检查并删除使用频率很低的索引;
5、定期采集slow query log,用pt-query-digest工具进行分析,可结合Anemometer系统进行slow query管理以便分析slow query并进行后续优化工作;
6、可使用pt-kill杀掉超长时间的SQL请求,Percona版本中有个选项 innodb_kill_idle_transaction 也可实现该功能;
7、使用pt-online-schema-change来完成大表的ONLINE DDL需求;
8、定期使用pt-table-checksum、pt-table-sync来检查并修复mysql主从复制的数据差异;
----
MySQL写出高效SQL的更多相关文章
- Oracle 如何写出高效的 SQL
转自:Oracle 如何写出高效的 SQL 要想写出高效的SQL 语句需要掌握一些基本原则,如果你违反了这些原则,一般情况下SQL 的性能将会很差. 1. 减少数据库访问次数连接数据库是非常耗时的,虽 ...
- 怎么避免写出慢SQL
在大多数实际的系统中,慢 SQL 消耗掉的数据库资源,往往是正常 SQL 的几倍.几十倍甚至几百倍. 怎样才能在开发阶段尽量避免写出慢 SQL 呢? 估算数据量 慢 SQL 对数据库的影响,是一个量变 ...
- 如何写出高性能SQL语句
优化SQL查询:如何写出高性能SQL语句 1.首先要搞明白什么叫执行计划? 执行计划是数据库根据SQL语句和相关表的统计信息作出的一个查询方案,这个方案是由查询优化器自动分析产生欀如一条SQL语句如果 ...
- Oracle如何写出高效的SQL
转载:http://www.blogjava.net/ashutc/archive/2009/07/19/277215.html 1.选择最有效率的表明顺序(只在基于规则的优化器中有效) Oracle ...
- 利用|,&,^,~,<<,>>>写出高效艺术的代码
简单介绍: 大家在阅读源代码的时候常常会看到一些比方以下这样特别难理解的代码. cancelEvent.setAction(MotionEvent.ACTION_CANCEL | (motionEve ...
- 理解SQL原理,写出高效代码
做软件开发的,大部分人都离不开跟数据库打交道,特别是erp开发的,跟数据库打交道更是频繁,存储过程动不动就是上千行,数据量大,人员流动大,那么我们还能保证下一段时间系统还能流畅的运行吗?我们还能保证下 ...
- 理解SQL原理,写出高效的SQL语句
我们做软件开发的,大部分人都离不开跟数据库打交道,特别是erp开发的,跟数据库打交道更是频繁,存储过程动不动就是上千行,如果数据量大,人员流动大,那么我们还能保证下一段时间系统还能流畅的运行吗?我们还 ...
- Mysql写出高质量的sql语句的几点建议
CleverCode在实际的工作也写过一些低效率的sql语句.这些语句会给数据库带来非常大的压力.最基本的表现就是sql语句执行慢,后来逐渐的去优化和尝试. 总结了一些高质量的sql语句的写法.这里C ...
- 优化SQL查询:如何写出高性能SQL语句
1. 首先要搞明白什么叫执行计划? 执行计划是数据库根据SQL语句和相关表的统计信息作出的一个查询方案,这个方案是由查询优化器自动分析产生的,比如一条SQL语句如果用来从一个 10万条记录的表中查1条 ...
随机推荐
- git 分支管理 (转自廖雪峰的git教程)
在版本回退里,你已经知道,每次提交,Git都把它们串成一条时间线,这条时间线就是一个分支.截止到目前,只有一条时间线,在Git里,这个分支叫主分支,即master分支.HEAD严格来说不是指向提交,而 ...
- ps(笔记)
窗口 工作区 默认窗口(恢复) ctrl + n 点阵图(像素图) 小方格组成的 alt 键 配合 放大缩小 ppi dpi 打印输出. 画布新建 z键 局部放大 右击实际像素操作 f键 全屏 空格键 ...
- iscroll.js的简单使用方法(总结)
iscroll.js的简单使用方法(总结) 一.总结 一句话总结:Scroll是一个类,每个需要使用滚动功能的区域均要进行初始化. 最佳的HTML结构如下: <div id="wrap ...
- Shell for、while循环
先顺带说下 if 1. if 条件;then else fi 如果else分支没有执行语句,可以不写. 2. if 条件;then elif 条件;then else fi #!/bin/bash ...
- python中配置文件的使用
一. 什么是配置文件?为什么要做配置文件? 将所有的代码和配置都变成模块化可配置化,这样就提高了代码的重用性,不再每次都去修改代码内部,这个就是我们逐步要做的事情,可配置化 二. python中的Co ...
- 【spark】常用转换操作:reduceByKey和groupByKey
1.reduceByKey(func) 功能: 使用 func 函数合并具有相同键的值. 示例: val list = List("hadoop","spark" ...
- win7 秘钥
链接 安装好Windows7后右击计算机--属性--更改产品密匙 输入以下密匙; RHTBY-VWY6D-QJRJ9-JGQ3X-Q2289 HT6VR-XMPDJ-2VBFV-R9PFY-3VP7R ...
- FindBugs初探
1. 什么是FindBugs FindBugs 是一个静态分析工具,它检查类或者 JAR 文件,将字节码与一组缺陷模式进行对比以发现可能的问题.有了静态分析工具,就可以在不实际运行程序的情况对软件进行 ...
- 自定义控件之TagGroup
转载请注明出处:http://blog.csdn.net/crazy1235/article/details/74907150 标签瀑布流布局! 实现方式有很多种. 继承LinearLayout 继承 ...
- poj1655(dfs,树形dp,树的重心)
这是找树的重心的经典题目. 树的重心有下面几条常见性质: 定义1:找到一个点,其所有的子树中最大的子树节点数最少,那么这个点就是这棵树的重心.定义2:以这个点为根,那么所有的子树(不算整个树自身)的大 ...