美文网首页
2020-11-18-Mysql(缓存 事务 索引 分析SQL执

2020-11-18-Mysql(缓存 事务 索引 分析SQL执

作者: 冰菓_ | 来源:发表于2020-11-26 08:25 被阅读0次

    查询缓存、事务

    my.cnf加入以下配置,重启MySQL开启查询缓存

    query_cache_type=1
    query_cache_size=600000

    执行命令开启缓存查询

    set global query_cache_type=1;
    set global query_cache_size=600000;

    还可以通过sql_cache和sql_no_cache来控制某个查询语句是否需要缓存:

    select sql_no_cache count(*) from usr;

    事务的四大特性:
    原子性(Atomicity): 事务是最小的执行单位,不允许分割。事务的原子性确保动作要么全部完成,要么完全不起作用;
    一致性(Consistency): 执行事务后,数据库从一个正确的状态变化到另一个正确的状态;
    隔离性(Isolation): 并发访问数据库时,一个用户的事务不被其他事务所干扰,各并发事务之间数据库是独立的;
    持久性(Durability): 一个事务被提交之后。它对数据库中数据的改变是持久的,即使数据库发生故障也不应该对其有任何影响。

    事务带来的并发问题:
    脏读事务A修改了某条数据,还没提交,与此同时,另一个事务读取了这个未提交的数据,结果造成了数据的脏读
    丢失修改:事务A修改了某条数据,与此同时另一个事务也修改了这条数据,结果导致事务A要修改值的更改,造成了数据的丢失
    不可重复读:与脏读的区别是,读取的是已经提交的数据,事务中包含事务,事务A比较大,在更新某条数据后进行了其他的操作,内部的事务更新提交了数据,事务A要修改的值发现了变化.
    幻读:对行的锁定,所有的事务依次逐个执行,与不可重复读的区别是幻读是插入数据,不可重复读是修改数据

    子查询慢的原因

    子查询的结果集无法使用索引,通常子查询的结果集会被存储到临时表中,不论是内存临时表还是磁盘临时表都不会存在索引,所以查询性能会受到一定的影响。特别是对于返回结果集比较大的子查询,其对查询性能的影响也就越大。

    由于子查询会产生大量的临时表也没有索引,所以会消耗过多的 CPU 和 IO 资源,产生大量的慢查询。

    分析一条SQL执行慢的原因的分析的流程

    1、大多数情况是正常的,只是偶尔会出现很慢的情况。

    • 数据库在刷新脏页(flush)

    当我们要往数据库插入一条数据、或者要更新一条数据的时候,我们知道数据库会在内存中把对应字段的数据更新了,但是更新之后,这些更新的字段并不会马上同步持久化到磁盘中去,而是把这些更新的记录写入到 redo log 日记中去,等到空闲的时候,在通过 redo log 里的日记把最新的数据同步到磁盘中去。

    当内存数据页跟磁盘数据页内容不一致的时候,我们称这个内存页为“脏页”。内存数据写入到磁盘后,内存和磁盘上的数据页的内容就一致了,称为“干净页”。

    刷脏页有下面4种场景:
    redolog写满了
    内存不够
    系统认为空闲的时候
    mysql正常关闭的时候

    • 拿不到锁:
      show processlist这个命令来查看当前的状态

    2、在数据量不变的情况下,这条SQL语句一直以来都执行的很慢。

    • 没用索引
      字段没有索引
      没用索引
    • 数据库选错索引
      1.系统判断是否走索引,扫描行数的预测其实只是原因之一,这条查询语句是否需要使用使用临时表、是否需要排序等也是会影响系统的选择的。
      2.强制走索引

    索引

    (参考)

    https://snailclimb.gitee.io/javaguide/#/docs/database/MySQL%20Index
    https://juejin.im/post/6844903645125820424

    聚集索引和非聚集索引

    简单概括:
    聚集索引就是以主键创建的索引
    非聚集索引就是以非主键创建的索引
    区别:
    聚集索引在叶子节点存储的是表中的数据
    非聚集索引在叶子节点存储的是主键和索引列
    使用非聚集索引查询出数据时,拿到叶子上的主键再去查到想要查找的数据。(拿到主键再查找这个过程叫做回表)

    聚合索引的二次查询问题

    非聚集索引叶节点仍然是索引节点,只是有一个指针指向对应的数据块,此如果使用非聚集索引查询,而查询列中包含了其他该索引没有覆盖的列,那么他还要进行第二次的查询,查询节点上对应的数据行的数据。
    非聚集索引是排序过的,与数据库中的数据并不是一一对应的
    这里的二级查询是在原来的索引的基础上查找还是,重新查找另一包含要查找数据的非聚集索引?

    理解:非聚集索引,逻辑位置和物理位置是不对应的,叶子节点存放的是主键id,假设存储的是索引列的物理位置,假设更新的话,就要更新这些物理位置,(非聚集索引是依赖于聚集索引的)

    覆盖索引

    如果一个索引包含(或者说覆盖)所有需要查询的字段的值,我们就称之为“覆盖索引”。我们知道InnoDB存储引擎中,如果不是主键索引,叶子节点存储的是主键+列值。最终还是要“回表”,也就是要通过主键再查找一次。这样就会比较慢覆盖索引就是把要查询出的列和索引是对应的,不做回表操作!

    最左前缀原则

    image.png

    关于日期的格式

    Datetime 和 Timestamp 之间抉择

    DateTime 类型是没有时区信息的(时区无关) ,DateTime 类型保存的时间都是当前会话所设置的时区对应的时间。这样就会有什么问题呢?当你的时区更换之后,比如你的服务器更换地址或者更换客户端连接时区设置的话,就会导致你从数据库中读出的时间错误

    Timestamp 和时区有关。Timestamp 类型字段的值会随着服务器时区的变化而变化,自动换算成相应的时间,说简单点就是在不同时区,查询到同一个条记录此字段的值会不一样。

    相关文章

      网友评论

          本文标题:2020-11-18-Mysql(缓存 事务 索引 分析SQL执

          本文链接:https://www.haomeiwen.com/subject/wsuqiktx.html