按照锁的粒度(级别、密度)分,MySQL有三种级别的锁:页级、表级、行级。
1、表级锁:开销小,加锁快;不会出现死锁;锁定粒度大,发生锁冲突的概率最
高,并发度最低。
2、行级锁:开销大,加锁慢;会出现死锁;锁定粒度最小,发生锁冲突的概率最
低,并发度也最高。
3、页面锁:开销和加锁时间界于表锁和行锁之间;会出现死锁;锁定粒度界于表
锁和行锁之间,并发度一般。
按禁止的操作可分为读锁和写锁,其中,互斥的关系如下
读锁 | 写锁 | |
---|---|---|
读锁 | 不互斥 | 互斥 |
写锁 | 互斥 | 互斥 |
一些重要的锁:
MDL锁 metadata lock 元数据锁
用于解决或保证DDL操作与DML操作之间的一致性。
属于表级锁。
间隙锁
间隙锁加锁规则详见丁奇老师的文章
自增id锁
trx_id锁
涉及到竞争资源,很多处都有锁。
小结一下:表锁、行锁、间隙锁(next-key lock)、自增id锁,MDL metadata lock 元数据锁
MySQL什么时候会使用内部临时表?
- 如果语句执行过程可以一边读数据,一遍直接得到结果,是不需要额外内存的,否则就需要额外的内存,来保存中间结果;
- join_buffer是无序数组,sort_buffer是有序数组,临时表是二维表结构;
- 如果执行逻辑需要用到二维表特性,就会优先考虑使用临时表。比如我们的例子中,union需要用到唯一索引约束,group by还需要用到另外一个字段来存累积计数。
MySQL常用操作
- explain查看命令优化器优化结果;
- show engine innodb status;
- show warnings,看优化器改写后的语句;
- show create table t; 查看t的建表语句;
MySQL中的重要概念
- MVCC(Multi View Concurrent Control)多视图并发控制,可重复读(RR,repeatable read)隔离级别下提供一致性视图的重要概念。以及MySQL巧妙的使用了undoLog来完成这些。
- redoLog,undoLog,binLog重要概念。
- WAL (write ahead log 技术),先将日志写在redolog中
- 索引的最左前缀规则(前缀索引规则),利用最左前缀规则,节省索引数量,节省空间。
- error log 错误日志,slow log慢查询日志(通过set long_query_time = 0,表示这个线程接下来的语句都会被记录入慢查询日志中;
- change buffer
- 普通索引和唯一索引尽量选择普通索引
- 对于字符串索引,可以用unique元素的百分比,也就是区分度,确定使用多长的字符串作为索引,语句为count distinct。预先设定一个可以接受的损失比例。但是使用前缀索引就用不上覆盖索引对查询性能的优化了,这也是你在选择是否使用前缀索引时需要考虑的一个因素。
- 脏页和干净页,redo log中的脏页,刷进磁盘才会删除。这时候系统会停止所有更新操作,把 checkpoint 往前推进,redo log 留出空间可以继续写。write_pos, checkpoint