mysql实战45讲

第1,2讲 sql执行步骤

在一个表上有更新的时候,跟这个表有关的查询缓存会失效,所以这条语句就会把表 T 上所有缓存结果都清空。这也就是我们一般不建议使用查询缓存的原因。接下来,分析器会通过词法和语法解析知道这是一条更新语句。优化器决定要使用 ID 这个索引。然后,执行器负责具体执行,找到这一行,然后更新。

mysql的两个日志,物理日志 redo log 和逻辑日志 binlog。

update两阶段提交:将 redo log 的写入拆成了两个步骤:prepare 和 commit。保证了两份日志逻辑一致

第3讲  事务隔离

  • 事务的特性ACID(原子性、一致性、隔离性、持久性)
  • 隔离级别:读未提交、读已提交、可重复读、和串行化

其中读已提交和可重复读是通过视图的方式实现的,读已提交是在每个sql开始执行的时候创建;可重复读是事务启动的时候创建;读未提交是直接返回记录上的最新值,串行化直接加锁,读写锁冲突就等待。

事务要避免长事务,因为长事务会导致回滚日志较大,回滚日志只有在没有比它更早的视图时才会删掉,即没有事务需要的时候,还可能会主从延迟。事务的启动有两种,一种是set autocommit=1,显式启动begin/start transaction,如果没有显式启动rollback不起作用;一种执行语句时直接启动

第4,5讲 索引

索引的结构类型:哈希表、有序数组和搜索树。innoDB使用了B+树,每个索引对应一棵B+树。

主键索引又叫聚簇索引,叶子存整行数据;非主键索引存主键的值。

如果表是一个索引直接将该索引设为主键索引,否则最好用自增索引,有两大好处:1,避免页分裂;2,降低了索引的内存。

覆盖索引(不一定是联合索引,查询的结果字段和条件字段在一个索引中,不需要回表)能减少树的搜索次数,显著提升查询性能。

最左前缀原则:查找联合索引的最左N个字段,也可以是字符串索引的最左M个字符,都支持使用索引。

联合索引建立还要考虑空间。比如建立a,b的索引,同时又有各自的查询,那么只需要单独为字段小的建立索引即可。

索引下推:mysql5.6之后,对索引中包含的字段做判断,减少回表。

第6,7讲  全局锁、表锁、行锁

innoDB支持事务,在myldump备份的时候使用-single-transaction就可以实现一致性读;可是MyISAM不支持事务,需要加全局读锁。

表级锁有两个,表锁和元数据锁(字段的增删),只有读锁不互斥。

两阶段锁协议:在 InnoDB 事务中,行锁是在需要的时候才加上的,但并不是不需要了就立刻释放,而是要等到事务结束时才释放。所以如果一个事务有多个锁,需要把最可能产生冲突,影响并发度的锁放到最后。

由于这个协议会产生死锁。解决办法有两个:1,等待直到事务超时;2,死锁检测。控制并发度会使死锁检测成本降低

第8讲   事务隔离

事务的实现是通过视图,视图的实现是通过行的多版本实现。

版本未提交,不可见;版本已提交,但是是在视图创建后提交的,不可见;版本已提交,而且是在视图创建前提交的,可见。

特别注意的一点,更新的总是当前值,即已提交的值。

第9讲 普通索引和唯一索引

查询过程:数据库是按数据页为单位读写的,普通索引找到后需要找下一个记录;唯一索引不需要,性能差距很小。

更新过程:普通索引可以使用change buffer,如果数据页不在内存,会将更新操作缓存在change buffer中。应用到原数据页(merge)的时机:1,查询;2,定期merge;3,正常关闭数据库。这样减少读磁盘,还能避免占用内存。唯一索引需要判断是否唯一,故不能使用。对于写多读少的场景很有优势。值得注意的一点:每次change buffer的操作都会写入redo log里。

第10讲 优化器选错索引

可能的情况:预估错扫描行数。解决方法:1:使用force index()强制;2:修改语句使其重新选择;3,使用analysisi table T重新统计索引信息。

第11讲 字符串索引

1:创建完整索引,占空间,可以用覆盖索引;2:前缀索引,节省空间,但会增加扫描次数;3,倒序存储,前缀索引,解决正序区分度不够的问题,不支持排序;4,hash索引字段索引,有可能冲突,还需要判断,也不支持排序。

第12讲 刷脏页

脏页:数据页和数据库的数据不一致称为脏页。刷脏页的时机:1:redo log写满;2:内存写满;3,空闲;4:主动关闭。

前两种会影响查询,解决办法:增大io大小,设置较大的redo log

第13讲 删数据并不能减少表空间

将数据从b+树删除后该空间是可复用状态,仍然占空间,只有重建表才能消除。重建表的语句是alter table t engine=InnoDB,mysql5.6后操作是Online DDL的,即期间可以增删改。

第14讲 count()

count(*)慢是因为事务的原因,只能现查,可以将总数存在数据库中。。count() 是一个聚合函数,对于返回的结果集,一行行地判断,如果 count 函数的参数不是 NULL,累计值就加 1,否则不加。count(字段)

 

你可能感兴趣的:(框架)