0
点赞
收藏
分享

微信扫一扫

【Web安全】XSS攻击与绕过

芷兮离离 03-08 11:30 阅读 3

优化

在MySQL中,如何定位慢查询

出现场景

  • 聚合查询
  • 多表查询
  • 表数据量过大查询
  • 深度分页查询
  • 表象:页面加载过慢,接口压测响应时间过长

方案一:开源工具

  • 调试工具: Arthas
  • 运维工具:Prometheus、Skywalking

方案二: MySQL自带慢日志

慢查询日志记录了所有执行时间超过指定参数(long_query_time, 单位:秒,默认10秒)的所有SQL语句的日志。如果要开启慢查询日志,需要在MySQL的配置文件中配置如下信息:

# 开启MySQL慢日志查询开关
slow_query_log=1
# 设置慢日志的时间为2s,SQL语句执行时间超过2s,就会视为慢查询,记录慢查询日志
long_query_time=2

SQL语句执行很慢,如何分析

可以采用EXPLAIN或者DESC命令获取MySQL如何执行SELECT语句的信息

  • 可以通过key或者key_len检查是否命中了索引(索引本身是否有失效的情况)
  • 通过type字段查看sql是否有进一步的优化空间,是否存在全盘索引或全盘扫描
  • 通过extra建议判断,是否出现了回表的情况。如果出现了,可以尝试添加索引或返回字段来修复
语法:
# 直接在select语句之前加上关键字 explain/desc
EXPLAIN SELECT 字段列表 FROM 表名 WHERE 条件;

在这里插入图片描述

  • possible_key 当前sql可能会使用到的索引
  • key 当前sql实际命中的索引
  • key_len索引占用的大小
  • Extra 额外的优化建议
  • type 这条sql连接的类型,性能由好到差为 NULL(未使用到)、system(mysql内置的表)、const(根据主键查询)、eq_ref(主键索引查询或唯一索引查询)、ref(索引查询,返回不止一条)、range(范围查询、最低要求)、index(索引树扫描)、all(全盘扫描)
    在这里插入图片描述

索引

了解过索引吗?(什么是索引)

  1. 索引是帮助MySQL高效获取数据的数据结构(有序)。
  2. 提高数据检索的效率,降低数据库的IO成本(不需要全盘扫描)
  3. 通过索引列对数据进行排序,降低数据排序的成本,降低了CPU的消耗。

索引的底层数据结构(InnoDB)

Mysql的InnoDB引擎使用的B+树的数据结构来存储索引

  • 相对于二叉树类型的数据结构,B+树的阶数更多,路径更短
  • 磁盘读写代价相对于B树更低,非叶子节点只存储指针,叶子节点存储数据
  • B+树便于扫库和区间查询,叶子节点是一个双向链表

B-tree

B-Tree,B树是一种多叉平衡查找树,相对于二叉树,B树的每个节点可以有多个分支,即多叉。

以一颗最大度数(max-degree)为5(5阶)的b-tree为例,那这个B树每个节点最多存储4个key
外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

B+树

B+树是在B树的基础上的一种优化,使其更加适合实现外存储索引结构。所有数据都存储在叶子节点上。

B树与B+树对比:

  1. 磁盘读写代价B+树更低
  2. 查询效率B+树更加稳定
  3. B+树更加便于扫库和区间查询

什么是聚簇索引和非聚簇索引

  • 聚簇索引(聚集索引):数据与索引放在一起,B+树的叶子节点保存了整行数据,有且只有一个。一般情况下主键作为聚簇索引
  • 非聚簇索引(二级索引):数据与索引分开存储,B+树的叶子节点保存对应的主键,可以有多个

什么是回表查询

通过二级索引找到对应的主键值,到聚集索引中查找整行数据,这个过程就是回表。

什么是覆盖索引

覆盖索引是指查询使用了索引,所返回的所有列在索引中全部能够找到

  • 使用id查询,直接利用聚集索引查询,一次索引扫描返回数据,性能高
  • 如果返回的列中没有创建索引,有可能会出发回表查询,尽量避免使用select *

MySQL超大分页怎么处理

在数据量比较大时,limit分页查询需要对数据进行排序,效率低。可以通过覆盖索引+子查询的方式来解决。

例如先分页查询数据的id字段,确定id后,再用子查询来过滤。只查询这个id列表中的数据就可以了。因为查询id的时候走的是覆盖索引,所以效率可以提升很多。

索引创建的原则有哪些

  1. 数据量较大,且查询比较频繁的表 , 至少表中的数据要超过10万以上⭐️
  2. 常作为查询条件、排序、分组的字段 ⭐️
  3. 字段内容区分度高
  4. 内容较长,使用前缀索引
  5. 尽量使用联合索引 ⭐️ 一条sql查询的返回值,尽量使用覆盖索引,即使一些字段的区分度不高,也放在组合索引后面的字段。
  6. 控制索引的数量 ⭐️ 添加索引会导致数据库增改变慢。
  7. 索引列不能存储NULL值,在创建表的时候使用NOT NULL约束

什么情况下索引会失效

  1. 违反最左前缀法则(多条索引要从第一个开始)
  2. 范围查询右边的列,不能使用索引
  3. 不要在索引列上进行运算操作,索引将失效
  4. 字符串不加单引号,造成索引失效。(类型转换)
  5. 以%开头的Like模糊查询,索引失效

通常情况下,想要判断是否出现索引失效的情况,可以使用explain执行计划来分析。

对SQL优化的经验

在这里插入图片描述

表的设计优化(参考阿里开发手册《嵩山版》)

  1. 设置合适的数值(tinyint、int、bigint),要更具实际情况选择
  2. 设置合适的字符串类型(char、varchar) char定长效率高,varchar可变长度,效率较低。

SQL语句优化

  1. SELECT语句务必指名字段名称,避免直接使用select *
  2. SQL语句避免造成索引失效的行为
  3. 尽量使用union all代替union。union会多一次过滤,效率低
  4. 避免在where自居中对字段进行表达式操作
  5. Join优化 能用inner join就不要使用left join 和right join。如必须使用,一定要用小表驱动大表。内连接会自动对两个表进行优化,优先把小表放在外则,大表放在里面。 left/right join 不会改变操作顺序。

主从复制,读写分离

如果数据库的使用场景中读的操作比较多的时候,为了避免写的操作所造成的性能影响,可以采用读写分离的架构。读写分离解决的是,数据库的写入影响了查询的效率。
在这里插入图片描述

其它

事务

事务的特点

事务是一组操作的集合,满足以下特性:

  1. 原子性(Atomicity):事务是不可分割的最小操作单元,要么全部成功,要么全部失败
  2. 一致性(Consistency):事务完成时,必须所有的数据都保持一致状态
  3. 隔离性(Isolation):数据库系统提供的隔离机制,保证事务在不受外部并发操作影响的独立环境下运行
  4. 持久性(Durability):事务一旦提交或回滚,它对数据库中数据的修改是永久的。
    在这里插入图片描述

并发事务带来哪些问题? 如何解决这些问题? MySQL的默认隔离级别是?

并发事务的问题
  • 脏读:一个事务读取到另一个事务还没有提交的数据
  • 不可重复读: 一个事务先后读取同一条记录,但两次读取的数据不同
  • 幻读: 一个事务按照条件查询数据时,没有对应的数据行,但是在插入数据时,又发现这条数据已经存在。
如何解决这些问题

通过设置MySQL的隔离级别可以解决这些问题,MySQL中存在四种不同的隔离级别

  1. READ UNCOMMITTED 未提交读 无法解决任何问题
  2. READ COMMITTED 读已提交 可解决脏读问题
  3. REPEATABLE READ 可重复读 可解决脏读和不可重复读问题
  4. SERIALIZABLE 串行化 可解决全部问题,但是性能低
MySQL的默认隔离级别

MySQL默认的隔离级别为可重复读

undo log 和 redo log 区别

缓冲池和数据页
  • 缓冲池:主内存中的一个区域,里面可以缓存磁盘上经常操作的真实数据。在执行增删改查操作时,先操作缓冲池中的数据(若缓冲池中没有数据,则从磁盘中加载并缓存),以一定的频率刷新到磁盘,从而减少磁盘IO,加快处理速度
  • 数据页: 是InnoDB存储引擎管理的最小单元,每个页的默认大小为16KB。页中存储的是行数据。
redo log

重做日志,记录事务提交时数据页的修改,是用来实现事务的持久性

该日志文件由两部分组成:重做日志缓冲(redo log buffer)以及重做日志文件(redo log file),前者在内存中,后者在磁盘中。当事务提交之后会把所有修改信息都存储到该日志文件中,用于在刷新脏页到磁盘,发生错误时,进行数据回复使用。

undo log

回滚日志,用于记录数据被修改前的信息,作用包括两个:提供回滚MVCC(多版本并发控制)。undo log 是逻辑日志,可以实现事务的一致性和原子性。

  • 可以认为每当delete一条记录时,undo log中会记录一条对应的insert记录,反之亦然
  • 当update一条记录时,会记录一条对应相反的update记录。当执行rollback时,就可以从undo log中的逻辑记录中读取到相应的内容并进行回滚。
undo log 与 redo log的区别
  • redo log:记录的是数据页的物理变化,服务宕机时可以用来同步数据。
  • undo log:记录的是逻辑日志,当事务回滚时,可以通过逆操作恢复原来的数据
  • redo log保证了事务的持久性, undo log 保证了事务的原子性和一致性

事务的隔离性如何保证(解释一下MVCC)

事务的隔离性主要是由MVCC实现的。

其中MVCC是指多版本并发控制,用于维护一个数据的多个版本,使读写操作没有冲突。其实现主要分为三个部分,包括隐藏字段, undo log日志和readview读视图。

隐藏字段是指在MySQL中每个表都设置了隐藏字段,有一个是trx_id,记录每一次操作的事务id,是自增的;另一个字段是roll_pointer(回滚指针),指向上一个版本的事务版本记录地址。

undo log的主要作用是记录回滚日志,存储老版本数据,在内部会形成一个版本链,在多个事务并行操作某一行记录时,记录不同事务修改数据库的版本,通过roll_pointer指针形成一个链表。

readView解决的是一个事务查询选择版本的问题,在内部定义了一些匹配规则和当前的一些事务id判断该访问哪个版本的数据。不同隔离级别读快照的规则不同,最终访问的结果页不一样。如果是rc隔离级别,会在每一次快照读的时候生成ReadView;如果是rr隔离级别,仅在事务中第一次执行快照的时候生成ReadView,后续不断复用第一次生成的ReadView。

MySQL主从同步

在这里插入图片描述

主从同步原理

MySQL主从复制的核心是二进制文件

  • 二进制日志(BINLOG)记录了所有DDL(数据定义语言)语句和DML(数据操纵语言)语句,但不包括数据查询(SELECT、SHOW)语句。

在这里插入图片描述

分库分表

在这里插入图片描述

举报

相关推荐

0 条评论