MySQL的性能优化理论(一)

本文涉及的产品
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS MySQL,高可用系列 2核4GB
简介: MySQL的性能优化理论

查询缓存

工作原理:

缓存SELECT操作的结果集和SQL语句;

新的SELECT语句, 先去查询缓存, 判断是否存在可用的记录集;

判断标准:

与缓存的SQL语句, 是否完全一样, 区分大小写
(简单认为存储了一个key-value结构, key为sql, value为sql查询结果集)

query_cache_type

值: 0 -– 不启用查询缓存, 默认值;

值: 1 -– 启用查询缓存, 只要符合查询缓存的要求, 客户端的查询语句和记录集

都可以缓存起来, 供其他客户端使用, 加上 SQL_NO_CACHE将不缓存

值: 2 -– 启用查询缓存, 只要查询语句中添加了参数: SQL_CACHE, 且符合查询

缓存的要求, 客户端的查询语句和记录集, 则可以缓存起来, 供其他客户端使用(按需开启)

query_cache_size

允许设置query_cache_size的值最小为40K, 默认1M, 推荐设置 为: 64M/128M;

query_cache_limit

限制查询缓存区最大能缓存的查询记录集, 默认设置为1M

show status like 'Qcache%' 命令可查看缓存情况

查询不会缓存的情况:

1.当查询语句中有一些不确定的数据时, 则不会被缓存。 如包含函数NOW(),

CURRENT_DATE()等类似的函数, 或者用户自定义的函数, 存储函数, 用户变

量等都不会被缓存

2.当查询的结果大于query_cache_limit设置的值时, 结果不会被缓存

3.对于InnoDB引擎来说, 当一个语句在事务中修改了某个表, 那么在这个事务

提交之前, 所有与这个表相关的查询都无法被缓存。 因此长时间执行事务,

会大大降低缓存命中率

4, 查询的表是系统表

5, 查询语句不涉及到表

为什么mysql默认关闭了缓存开启?  

1.在查询之前必须先检查是否命中缓存,浪费计算资源

2.如果这个查询可以被缓存, 那么执行完成后, MySQL发现查询缓存中没有这

个查询, 则会将结果存入查询缓存, 这会带来额外的系统消耗

3.针对表进行写入或更新数据时, 将对应表的所有缓存都设置失效。

4.如果查询缓存很大或者碎片很多时, 这个操作可能带来很大的系统消耗

适用场景:

以读为主的业务, 数据生成之后就不常改变的业务

比如门户类、 新闻类、 报表类、 论坛类等

 

查询优化处理的三个阶段

• 解析sql

通过lex词法分析,yacc语法分析将sql语句解析成解析树

https://www.ibm.com/developerworks/cn/linux/sdk/lex/

• 预处理阶段

根据mysql的语法的规则进一步检查解析树的合法性, 如: 检查数据的表

和列是否存在, 解析名字和别名的设置。 还会进行权限的验证

• 查询优化器

优化器的主要作用就是找到最优的执行计划

 

查询骑如何找到最优执行计划

1.使用等价变化规则     5 = 5 and a > 5 改写成 a > 5   a < b and a = 5 改写成 b > 5 and a = 5

2.外连接自动转为内连接

3.基于联合索引, 调整条件位置等

4. 优化count 、 min、 max等函数.   min函数只需找索引最左边,max函数只需找索引最右边,myisam引擎count(*)

5. 覆盖索引扫描

6.子查询优化

7.提前终止查询 用了limit关键字或者使用不存在的条件

8.IN的优化         先进行排序, 再采用二分查找的方式

Mysql的查询优化器是基于成本计算的原则。 他会尝试各种执行计划。

数据抽样的方式进行试验( 随机的读取一个4K的数据块进行分析)

explian各个字段的含义

type

访问类型, sql查询优化中一个很重要的指标, 结果值从好到坏依次是:

system > const > eq_ref > ref > range > index > ALL

system: 表只有一行记录( 等于系统表) , const类型的特例, 基本不会出现, 可以忽略不计

const: 表示通过索引一次就找到了, const用于比较primary key 或者 unique索引

eq_ref: 唯一索引扫描, 对于每个索引键, 表中只有一条记录与之匹配。 常见于主键 或 唯一索引扫描

ref: 非唯一性索引扫描, 返回匹配某个单独值的所有行, 本质是也是一种索引访问

range: 只检索给定范围的行, 使用一个索引来选择行

index: Full Index Scan, 索引全表扫描, 把索引从头到尾扫一遍

ALL: Full Table Scan, 遍历全表以找到匹配的行

possible_keys

查询过程中有可能用到的索引

key

实际使用的索引, 如果为NULL, 则没有使用索引

rows

根据表统计信息或者索引选用情况, 大致估算出找到所需的记录所需要读取的行

filtered

它指返回结果的行占需要读到的行(rows列的值)的百分比

表示返回结果的行数占需读取行数的百分比, filtered的值越大越好

Extra

1、 Using filesort :

mysql对数据使用一个外部的文件内容进行了排序, 而不是按照表内的索引进行排序读取

2、 Using temporary:

使用临时表保存中间结果, 也就是说mysql在对查询结果排序时使用了临时表, 常见于order by 或 group by

3、 Using index:

表示相应的select操作中使用了覆盖索引( Covering Index) , 避免了访问表的数据行, 效率高

4、 Using where :

使用了where过滤条件

5、 select tables optimized away:

基于索引优化MIN/MAX操作或者MyISAM存储引擎优化COUNT(*)操作, 不必等到执行阶段在进行计算, 查询执行计划生成的阶段即可完成优化

慢查询日志的使用

配置

show variables like 'slow_query_log'

set global slow_query_log = on

set global slow_query_log_file = '/var/lib/mysql/gupaoedu-slow.log'

set global log_queries_not_using_indexes = on

set global long_query_time = 0.1 (秒)

日志分析

Time : 日志记录的时间

User@Host: 执行的用户及主机

Query_time: 查询耗费时间 Lock_time 锁表时间 Rows_sent 发送给请求方的记录

条数 Rows_examined 语句扫描的记录条数

SET timestamp 语句执行的时间点

select .... 执行的具体语句

分析工具

mysqldumpslow -t 10 -s at /var/lib/mysql/gupaoedu-slow.log

InnoDB的锁

一.锁的类型

共享锁:

又称为读锁, 简称S锁, 顾名思义, 共享锁就是多个事务对于同一数据可以共享一把锁,

都能访问到数据, 但是只能读不能修改;

加锁释锁方式:

select * from users WHERE id=1 LOCK IN SHARE MODE;

commit/rollback

排他锁:

又称为写锁, 简称X锁, 排他锁不能与其他锁并存, 如一个事务获取了一个数据行的排他

锁, 其他事务就不能再获取该行的锁( 共享锁、 排他锁) , 只有该获取了排他锁的事务是可以对

数据行进行读取和修改, ( 其他事务要读取数据可来自于快照)

加锁释锁方式:

delete / update / insert 默认加上X锁

SELECT * FROM table_name WHERE ... FOR UPDATE

commit/rollback

意向共享锁(IS):

表示事务准备给数据行加入共享锁, 即一个数据行加共享锁前必须先取得该表的IS锁,

意向共享锁之间是可以相互兼容的

意向排它锁(IX):

表示事务准备给数据行加入排他锁, 即一个数据行加排他锁前必须先取得该表的IX锁,

意向排它锁之间是可以相互兼容的

意向锁(IS、 IX)是InnoDB数据操作之前自动加的, 不需要用户干预

意义:当事务想去进行锁表时, 可以先判断意向锁是否存在, 存在时则可快速返回该表不能
启用表锁

理解:意向锁相当于一个判断锁是否被锁定过的flag

自增锁(AUTO-INC Locks)

针对自增列自增长的一个特殊的表级别锁

show variables like 'innodb_autoinc_lock_mode';

默认取值1, 代表连续, 事务未提交ID永久丢失

临间锁(Next-key locks):

锁住记录+区间(左开右闭)

当sql执行按照索引进行数据的检索时,查询条件为范围查找( between and、 <、 >等) 并有数

据命中则此时SQL语句加上的锁为Next-key locks, 锁住索引的记录+区间( 左开右闭)

      防止幻读

间隙锁(Gap Locks)

当sql执行按照索引进行数据的检索时, 查询条件的数据不存在, 这时SQL语句加上的锁即为

Gap locks, 锁住索引不存在的区间( 左开右开)

Record locks:

锁住具体的索引项

当sql执行按照唯一性( Primary key、 Unique key) 索引进行数据的检索时, 查询条件等值匹配且查询的数据是存在, 这时SQL语句加上的锁即为记录锁Record locks, 锁住具体的索引项

 

二、利用锁类解决脏读、不可重复读、幻读

三、InnoDB行锁到底锁了什么

InnoDB的行锁是通过给索引上的索引项加锁来实现的。
只有通过索引条件进行数据检索,InnoDB才使用行级锁,否则,InnoDB将使用表锁(锁住索引的所有记录)

表锁:lock tables xx read/write

 

四、死锁

1)类似的业务逻辑以固定的顺序访问表和行。

2)大事务拆小。大事务更倾向于死锁,如果业务允许,将大事务拆小。

3)在同一个事务中,尽可能做到一次锁定所需要的所有资源,减少死锁概

率。

4)降低隔离级别,如果业务允许,将隔离级别调低也是较好的选择

5)为表添加合理的索引。可以看到如果不走索引将会为表的每一行记录添

加上锁(或者说是表锁)


相关实践学习
如何在云端创建MySQL数据库
开始实验后,系统会自动创建一台自建MySQL的 源数据库 ECS 实例和一台 目标数据库 RDS。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助 &nbsp; &nbsp; 相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
5月前
|
存储 关系型数据库 MySQL
《MySQL 简易速速上手小册》第3章:性能优化策略(2024 最新版)
《MySQL 简易速速上手小册》第3章:性能优化策略(2024 最新版)
74 2
|
4月前
|
存储 关系型数据库 MySQL
MySQL数据库进阶第三篇(MySQL性能优化)
MySQL数据库进阶第三篇(MySQL性能优化)
|
21天前
|
存储 SQL 关系型数据库
【MySQL调优】如何进行MySQL调优?从参数、数据建模、索引、SQL语句等方向,三万字详细解读MySQL的性能优化方案(2024版)
MySQL调优主要分为三个步骤:监控报警、排查慢SQL、MySQL调优。 排查慢SQL:开启慢查询日志 、找出最慢的几条SQL、分析查询计划 。 MySQL调优: 基础优化:缓存优化、硬件优化、参数优化、定期清理垃圾、使用合适的存储引擎、读写分离、分库分表; 表设计优化:数据类型优化、冷热数据分表等。 索引优化:考虑索引失效的11个场景、遵循索引设计原则、连接查询优化、排序优化、深分页查询优化、覆盖索引、索引下推、用普通索引等。 SQL优化。
168 15
【MySQL调优】如何进行MySQL调优?从参数、数据建模、索引、SQL语句等方向,三万字详细解读MySQL的性能优化方案(2024版)
|
11天前
|
存储 关系型数据库 MySQL
mysql-性能优化(一)
mysql-性能优化(一)
|
19天前
|
关系型数据库 MySQL 数据处理
针对MySQL亿级数据的高效插入策略与性能优化技巧
在处理MySQL亿级数据的高效插入和性能优化时,以上提到的策略和技巧可以显著提升数据处理速度,减少系统负担,并保持数据的稳定性和一致性。正确实施这些策略需要深入理解MySQL的工作原理和业务需求,以便做出最适合的配置调整。
73 6
|
5天前
|
SQL 存储 关系型数据库
深入 MySQL 的执行计划与性能优化
深入 MySQL 的执行计划与性能优化
13 0
|
2月前
|
存储 关系型数据库 MySQL
"深入探索MySQL临时表:性能优化利器,数据处理的灵活之选"
【8月更文挑战第9天】MySQL临时表专为存储临时数据设计,自动创建与删除,仅在当前会话中存在,有助于性能优化。它分为本地临时表和全局临时表(通过特定逻辑模拟)。创建语法类似于普通表,但加TEMPORARY或TEMP关键字。适用于性能优化、数据预处理和复杂查询,需注意内存占用和事务支持问题。合理使用可大幅提升查询效率。
106 2
|
3月前
|
SQL 存储 数据库
MySQL设计规约问题之性能分析工具如Sql explain、show profile和mysqlsla在数据库性能优化中有什么作用
MySQL设计规约问题之性能分析工具如Sql explain、show profile和mysqlsla在数据库性能优化中有什么作用
|
4月前
|
SQL 关系型数据库 MySQL
MySQL性能优化实战:从索引策略到查询优化
MySQL性能优化聚焦索引策略和查询优化。创建索引如`CREATE INDEX idx_user_id ON users(user_id)`可加速检索;复合索引考虑字段顺序,如`idx_name ON users(last_name, first_name)`。使用`EXPLAIN`分析查询效率,避免全表扫描和大量`OFFSET`。通过子查询优化分页,如LIMIT配合内部排序。定期审查和调整策略以提升响应速度和降低资源消耗。【6月更文挑战第22天】
617 2
|
4月前
|
存储 关系型数据库 MySQL
深入探索MySQL:成本模型解析与查询性能优化
深入探索MySQL:成本模型解析与查询性能优化
下一篇
无影云桌面