MySQL常见优化

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 by

  • using 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 where

  • impossible 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 表中
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,670评论 5 460
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,928评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,926评论 0 320
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,238评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,112评论 4 356
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,138评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,545评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,232评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,496评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,596评论 2 310
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,369评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,226评论 3 313
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,600评论 3 299
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,906评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,185评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,516评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,721评论 2 335