前言:
目录:
一、索引(覆盖索引,索引合并,索引跳跃扫描MySQL8.0,自适应哈希索引)
二、事物
三、锁
四、性能
五、问题排查
六、高可用(了解)
七、新特性(了解)
一、索引
1.1 覆盖索引:当查询的列都包含在索引中时,mysql可以直接从索引中获取数据,避免回表操作,提高查询效率。
CREATE INDEX idx_user_email ON users(email);
SELECT email FROM users WHERE email LIKE '%@example.com%';
1.2 索引合并:mysql可以同时使用多个单列索引,并将他们的结果合并,以满足负载的查询条件。
CREATE INDEX idx_age ON users(age);
CREATE INDEX idx_city ON users(city);
SELECT * FROM users WHERE age = 30 OR city = 'New York';
1.3 索引跳跃扫描:mysql8.0引入的优化策略,允许在联合索引中跳过最左前缀,适合用于联合索引的首列基数较低的情况。
CREATE INDEX idx_a_b ON t(a, b);
SELECT * FROM t WHERE b = 100;
1.4 自适应哈希索引:InnoDB存储的引擎会自动监控访问模式,对频繁访问的B+Tree索引页建立哈希索引,以加速查询。
**使用场景**:频繁访问相同页的数据。
> 开启方式:默认启用,可通过 `innodb_adaptive_hash_index` 参数控制。
个人理解:不用刻意操作
查看当前表的索引
SHOW INDEX FROM t_sdata_plugin_property;
2 B+树索引原理与实现
B+tree是mysql默认的索引结构,具有以下特点:
- 所有数据存储在叶子节点,非叶子节点只存储索引信息。
- 叶子节点之间通过指针连接,支持范围查询。
- 树的高度较低,通常为2-4层,查找效率比较高。
二、事务
明确事务的四大特性:原子性,一致性,隔离性,持久性。(ACID)
1.1 隐式提交
执行DDL或者没有显示开启事务时,自动提交事务
INSERT INTO t VALUES (1); -- 自动提交
1.2 保存点
START TRANSACTION;
INSERT INTO t VALUES (1);
SAVEPOINT sp1;
INSERT INTO t VALUES (2);
ROLLBACK TO sp1; -- 回滚第二次插入
1.3 XA分布式事务
三阶段协议:
- XA START
- XA END / PREPARE
- XA COMMIT / ROLLBACK
1.4 日志
- redo log 崩溃恢复 事务执行中 性能影响小
- binlog 主从复制 事务提交后 同步模式影响大
- undo log 事务回滚 数据修改前 内存操作为主
三、锁
1.1 意向锁(自动) 表级锁,表示即将在行级加锁
- 意向共享锁 (IS):表明事务打算在某些行上设置共享锁
- 意向排他锁 (IX):表明事务打算在某些行上设置排他锁
1.2 插入意向锁(自动) 多个事务可并发插入不同区间,不互相阻塞
1.3 自增锁(自动) 对自增字段的保护,串行化写入
1.4 外键锁(自动) 在插入/更新外键时锁住父表对应行,避免约束破坏。
四、性能
1.1 子查询优化
非推荐写法:
SELECT name FROM t WHERE id IN (SELECT id FROM t2);
优化写法:
SELECT t.name FROM t JOIN t2 ON t.id = t2.id;
1.2 临时表优化
- 避免group by/order by使用不必要的列
- 避免使用TEXT/BLOB字段
1.3 ICP(索引条件下推)
在普通的查询过程中,即使我们使用了索引,如果where子句中有些条件不在索引上,mysql也必须先通过索引定位主键,再回表取完整行数据,再进行过滤。 而ICP会把能在索引中判断的部分条件提前在存储引擎层做判断,如果不满足就不回表直接丢弃,也就是说在回表之前就会过滤掉一部分数据,节省了大量回表的成本。
假设有表
CREATE TABLE employees (
id INT PRIMARY KEY,
name VARCHAR(100),
age INT,
department_id INT,
INDEX idx_age_dept(age, department_id)
);
SELECT * FROM employees WHERE age > 30 AND department_id = 5;--执行
不使用ICP时:
- MySQL 使用 `idx_age_dept` 遍历 `age > 30`;
- 然后对每一行都 **回表获取整行数据**;
- 然后在服务器层判断 `department_id = 5`。
使用ICP时:
- MySQL 同样用 `idx_age_dept` 遍历 `age > 30`;
- **在索引本身就能判断 `department_id = 5`**,只保留满足条件的索引条目;
- **只有这些才回表**,极大减少 IO。
判断ICP是否生效
EXPLAIN SELECT * FROM employees WHERE age > 30 AND department_id = 5;
显示:
Extra: Using index condition --生效
五、问题排查
1.1 MySQL状态排查
-
SHOW PROCESSLIST 查看慢查询/锁等待,查看当前连接、是否有阻塞
-
SHOW ENGINE INNODB STATUS 分析锁和死锁
-
SHOW GLOBAL STATUS 查看系统指标
-
SHOW VARIABLES 查看关键参数配置
-
SHOW SLAVE STATUS 查看复制延迟秒数
-
SHOW PROCESSLIST 查看是否有大事务
-
SHOW VARIABLES LIKE 'slave_parallel_workers' 是否开启并行复制
六、高可用
1.1 故障自动切换
- 持续监控主从复制状态
- 主库故障时自动提升最优从库为新主库
- 自动重建复制拓扑
1.2 延迟从库
- 防止人为误操作(提供"时间回退"能力)
- 应对逻辑损坏(如错误的UPDATE语句)
CHANGE MASTER TO
MASTER_DELAY = 3600; -- 延迟1小时
# 临时取消延迟(紧急恢复)
STOP SLAVE;
CHANGE MASTER TO MASTER_DELAY = 0;
START SLAVE;
1.3 多源复制
七、新特性
1.1 窗口函数 典型场景:销售排名分析
SELECT
product_id,
sale_date,
amount,
SUM(amount) OVER (PARTITION BY product_id ORDER BY sale_date) AS running_total,
RANK() OVER (PARTITION BY YEAR(sale_date) ORDER BY amount DESC) AS yearly_rank,
LAG(amount, 1) OVER (PARTITION BY product_id ORDER BY sale_date) AS prev_day_amount
FROM sales
WHERE sale_date BETWEEN '2023-01-01' AND '2023-12-31';
1.2 JSON增强
1.3 直方图统计
1.4 CTE(通用表表达式)