1,MySQL版本:
- MySQL Community Server 社区版本,开源免费,但不提供官方技术支持。
- MySQL Enterprise Edition 企业版本,需付费,可以试用30天。
- MySQL Cluster 集群版,开源免费。可将几个MySQL Server封装成一个Server。
- MySQL Cluster CGE 高级集群版,需付费。
- MySQL Workbench(GUI TOOL)一款专为MySQL设计的ER/数据库建模工具。它是著名的数据库设计工具DBDesigner4的继任者。MySQL Workbench
又分为两个版本,分别是社区版(MySQL Workbench OSS)、商用版(MySQL Workbench SE)。
MySQL Community Server 是开源免费的,这也是我们通常用的MySQL的版本。根据不同的操作系统平台细分为多个版本,
5.X:
5.0-5.1:早期产品的延续,升级维护
5.4 - 5.x :MySQL整合了第三方公司的新存储引擎 (5.5 5.7)
https://blog.csdn.net/vtopqx/article/details/87934889
2,mysql逻辑分层:连接层,服务层,引擎层,存储层
https://www.cnblogs.com/sunjingwu/p/9732371.html
3,存储引擎
- inndb
事务有限 行锁 - myisam
性能优先 表锁
查看当前的存储引擎:
show engines ;
show variables like '%storage_engine%'
4,SQL优化
原因:SQL问题(链接查询),索引失效,服务器参数设置问题(缓冲区,线程数设置不合理)
1,SQL:解析过程,from,on,join,where, group by, having. select, order by ,limit SQL解析过程
2,SQL优化,主要就是优化索引
3,什么是索引:相当于书的目录,索引是帮助MySQL高效获取数据的数据结构 ,索引是数据结构(默认B树)
4,索引本身很大,需要占用内存和硬盘。不是所有情况都适用,频繁更新的字段不适合
建立索引会降低增删改的效率
B树:https://www.bilibili.com/video/av36069871?from=search&seid=1181095641637380064
5,索引
- 单值索引:单列,一个表内可以多个单值索引
- 唯一索引:不能重复
- 复合索引:多个列构成的索引
6,SQL性能问题
1,分析SQL的执行计划:explain 可以模拟SQL优化器执行SQL语句
- explain + sql语句 查询执行计划
- select_type :查询类型
- table :表
- type :类型
- possible keys :预测用到的索引
- key: 实际使用的索引
- key_len :实际使用索引的长度
- ref:表之间的引用
- rows:通过索引查到的数据量
- extra:额外的信息
2,explain详解:
id:
值相同 从上往下,顺序执行
多表内连接查询,表执行顺序,因数量的个数改变而改变的原因:笛卡尔积
数据小的表,优先查询
id值不同,越大越优先查询
select_type
- primary 包含子查询SQL中的主查询(最外层)
- subquery 包含子查询SQL中的子查询(非最外层)
- simple:简单查询,不包含子查询,union
- derived:衍生查询,查询的时候用到了临时表
- from 子查询 中只有一张表,临时表 select * from(select * from t where t.id in (1,2))tr
- 在from 子查询中,如果有两张 两张表 union查询,则前面的查询是衍生查询,第二张表则叫union ,
select * from(select * from t where t.id = 1 union select * from t where t.id = 2)tr - union:union查询的除最左表的右表则是union查询
- union Result:指union 连接出来的临时表
type
越左性能越好
system> const>eq_ref>ref>range>index>all
system,const 只是理想情况,实际能达到ref>range
要对type进行优化的前提 是有索引
system:只有一条数据的系统表,或衍生表只有一条数据的主查询(select * from (select * from t ) t where id = 1) t表只有一条数据
const:仅仅能查到一条数据的SQL,用于primary key 或unique 索引
eq_ref:唯一性索引,对于每个索引键的查询,返回匹配唯一行数据,有且只能有一条数据
常见于唯一索引,和主键索引ref:非唯一性,对于每个索引键的查询,返回匹配的所有行(0,多)
select * from t where name = 'zs' zs 不唯一range:检索指定范围的行,where 后面是范围查询(between,in ,> < )in可能会失效变成无索引all
index:查询全部索引中数据
all:查询全部表数据
type——小结
system/const:结果只有一条数据
eq_ref:结果多条,但是每条数据是唯一的
ref:结果多条,每条数据可以是0或者多条
possible_keys
可能用到的索引。预测用到的索引
key
实际使用到的索引, 如果是null 则是没有索引
key_len
索引长度:用于判断符合索引是否被完全使用
utf8 一个字符 3个字节 一个字节表示可以为null 两个字节表示可变长度
ref
指明当前表所 参照的字段,常量列 const,=‘’等于某个常量
引用字段 t.id = c.id
rows
行数,被索引优化查询的数据个数,通过条件查询出来的数据个数
extra
using filesort:性能消耗大,需要额外一次排序(查找) where a='' order by b 常见于order by
对于单索引,如果排序和查找是同一个字段则不会出现using filesort,反之
复合索引,不能跨列,并且最佳最前缀
单索引:where 什么字段 order by什么字段
复合索引:where 和 order by按照复合索引的顺序使用,不要跨列或无序使用using temporary 性能损耗大,用到临时表,
一般出现group by 中,出现在select a2 from t group by a1
避免:where什么列,就根据哪些列group byusing index:性能提升,索引覆盖。
不读取源文件,只从索引文件中获取数据,不需要回表查询
(不回表查询:如果 select age from t where age = 1 ,假设age是索引列,那么只需要到索引树当中查询数据不需要回表查询其他的数据)
出现不回表查询则出现using index,
如果索引覆盖 (using index) 会对possible_keys 和 keys造成影响
如果没有where,则索引只出现在key中
如果有where,则出现在key 和 possible_keys中
using where:需要回表查询,则会出现using where
select age,name from where age = 1 ,假设age是索引,则此语句需要回表查询会出现using whereimpossible where:where 字句永远为false
3,SQL优化:
复合索引不能跨列,否则索引失效,可以通过key_len 来观察是否使用到索引
补充using filesort:复合索引不要跨列使用(where 和 order by 拼起来)没有跨列
where 和 order by 拼起来是否满足复合索引顺序,满足则不会出现using filesort反之
1,如果(a,b,c,d)复合索引 和使用的顺序全部一致,则复合索引全部使用,如果部分一致
则使用部分索引 select a,c where a = and b= and c= and d= 和索引顺序完全一致(不跨列使用)则复合索引全部使用
2,单表优化:根据SQL实际的解析顺序,调整复合索引的顺序(最佳左前缀)
索引需要逐步优化。将含in的范围查询放到where 的最后防止失效,失效则会导致后面的索引失效,并且需要回原表查询
3,多表优化:小表驱动大表,索引建立在经常使用的字段上,左外连接 给外表加索引。
4,避免索引失效的原则
(SQL优化是一种概率事件,并不一定达到预想情况)失效的情况大部分适用
索引优化 是一个大部分情况适用的结论,但由于SQL优化器等原因,结论不是百分百正确
一般情况,范围查询(>< in),之后的索引失效
尽量使用索引覆盖,索引不会失效(using index)
in 会使索引失效,
复合索引不要跨列(where+order by拼接起来 ),或者无序使用(最佳最前缀)
复合索引尽量使用全索引匹配
不要在索引上进行任何操作,比如计算,函数。否则索引失效
复合索引只要左边有一个失效则右边的索引全部失效
复合索引不能使用 不等于,is null,is not null。否则自身已经右侧索引全部失效
like 尽量以常量开头,不要以%开头,否则索引失效
尽量不要包含类型转换(显示,隐式)varchar 字段 = 123 。存在隐式转换
尽量不要使用or ,否则索引失效
5,SQL优化方法。
1,exist 和 in 如果主查询的数据集大用 in,如果子查询数据集大,则使用exist
2,order by,经常看到using filesort 有两种算法,双路排序和单路排序,根据IO的次数
- 双路排序:双路:扫描两次磁盘。第一次扫描排序字段,排序在buffer 缓冲区进行排序,第二次扫描其他字段
- 单路排序:只读取一次(全部字段),在buffer中进行排序,但此种单路排序会有一定的隐患,不一定真的是“单路”1次IO,有可能多次IO
如果数据量特别大,则无法将所有字段的数据读取完毕,进行分片读取,多次读取。单路排序比双路排序占用更多的buffer缓冲区
可以考虑buffer的容量大小:set max_length_for_sort_data = 1024(字节)
如果set max_length_for_sort_data值太低,则MySQL会自动从 单路排序切换到双路排序。(太低:需要排序列的总大小超过了max_length_for_sort_data定义的字节数)
提高order by查询的策略:选择使用单路,双路;调整buffer的容量大小,避免select * ,保证全部的排序字段 排序的一致性(都是升序 或 降序)
6,SQL排序-慢查询日志
MYSQL提供的日志记录,用于记录MySQL响应时间超过阈值的SQL语句(long_query_time,默认十秒)
慢查询日志默认是关闭的,建议,开发调优时打开,而在最终部署时关闭。
检查是否开启慢查询日志:show variables like '%slow_query_log%',
开启慢查询日志
1,临时开启:set global slow_query_log = 1 内存中开启
2,永久开启:/etc/my.cnf 中追加配置 [mysqld] slow_query_log=1 slow_query_log_file=日志路径
慢查询阈值:show variables like '%long_query_time%'
1,临时设置:set global long_query_time,设置完毕重新登录
2,永久设置:/etc/my.cnf 中追加配置[mysqld] long_query_time=3
查询超过阈值的SQL条数:show global status like '%slow_queries%'
通过日志查看具体的慢SQL,通过mysqldumpslow工具
7,分析海量数据
- show variables like '%profiling%'
set profiling = no 开启
show profiles; 会记录所有profiling 打开后所有执行的语句所花费的时间。只能看到总共消费时间。 - 精确分析:sql 诊断
show profile all for query 查询到的SQLid - 全局查询日志:记录开始之后的 全部SQL语句。(调优过程中打开)
show variables like '%general_log%' set global general_log = 1,set global log_output='table'
开启全局日志 开启之后记录所有SQL,会被记录到MySQL general_log 表中