0%

MySQL 中 IN 和 EXISTS 的取舍:原理与最佳实践

在 SQL 查询中,INEXISTS 都用于实现子查询条件过滤,但两者的执行逻辑和性能表现存在显著差异。掌握它们的适用场景,能有效提升查询效率,核心原则是 “小表驱动大表”—— 让数据量少的表作为外层循环,减少总迭代次数。

IN 与 EXISTS 的执行原理

IN 子查询:先执行子查询,再匹配外层表

IN 的执行逻辑是 “先子查询,后外层查询”,适合外层表大、子查询结果小的场景。

语法与等价逻辑:
1
2
3
4
5
6
-- 原查询
SELECT * FROM A WHERE id IN (SELECT id FROM B);

-- 等价执行步骤:
1. 先执行子查询,获取 B 表的 id 集合(如结果为 [1,2,3]),并生成临时表存储。
2. 遍历 A 表,判断每条记录的 id 是否在临时表中,匹配则保留。
特点:
  • 子查询只执行一次,结果存储在临时表中(内存或磁盘)。
  • 外层表需全表扫描(或使用索引),逐条与子查询结果匹配。
  • 子查询结果集越大,临时表占用空间越多,匹配效率越低。

EXISTS 子查询:先执行外层表,再用子查询验证

EXISTS 的执行逻辑是 “先外层查询,后子查询验证”,适合外层表小、子查询表大的场景。

语法与等价逻辑:
阅读全文 »

MySQL 索引详解

什么是 MySQL 索引

索引是帮助 MySQL 快速查找数据的数据结构,它通过某种方式指向数据,并基于该结构实现高效查找算法,从而加速数据检索。

MySQL 默认使用的是 B-Tree 索引(实际结构为 B + 树),这是最常用的索引类型。

索引的分类

1. 普通索引

最基础的索引,无任何约束,仅用于加速查询。

2. 唯一索引

与普通索引类似,但附加唯一性约束(允许空值,但空值只能出现一次),可避免数据重复。

3. 主键索引

特殊的唯一索引,不允许空值,每张表只能有一个主键索引。MySQL 会自动为主键创建主键索引。

4. 复合索引

将多个列组合创建的索引,可覆盖多列查询条件,查询时需遵循 “最左前缀法则”。

5. 外键索引

仅 InnoDB 引擎支持,用于维护表之间的关联关系,保证数据的一致性、完整性,并支持级联操作。

6. 全文索引

用于全文检索,MySQL 自带的全文索引仅支持 InnoDB(5.6+)和 MyISAM 引擎,且对中文支持有限(5.7 + 通过 ngram 插件支持)。实际场景中,更常用专业全文索引引擎(如 Elasticsearch、Solr)。

索引的操作语法

创建索引

阅读全文 »

MySQL 执行计划详解:读懂 Explain,优化 SQL 不求人

执行计划(Explain)是 MySQL 优化的 “导航图”,它能模拟优化器执行 SQL 的过程,展示 MySQL 如何解析和执行你的查询。掌握执行计划的分析方法,是写出高效 SQL 的前提。本文将系统拆解执行计划的每个字段,教你如何通过 Explain 定位性能瓶颈。

执行计划的基本使用

通过EXPLAIN关键字可以生成执行计划,语法简单:

1
2
3
4
5
6
-- 基础用法
EXPLAIN SELECT * FROM user WHERE age > 18;

-- 结合索引未使用的原因(配合show warnings)
EXPLAIN SELECT * FROM user WHERE age > 18;
SHOW WARNINGS; -- 显示优化器对SQL的改写和分析

执行后会生成一张包含 12 个字段的表格,每个字段都隐藏着查询的关键信息:

1
2
3
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-------+

执行计划字段详解

1. id:查询执行顺序标识

表示 SELECT 子句或操作表的序号,决定执行顺序

  • id 相同:执行顺序由上至下(按 table 字段顺序)。
    例:多表连接查询中,id 相同表示按表的出现顺序依次访问。
  • id 不同:id 越大优先级越高,先执行(子查询的 id 通常大于外层查询)。
    例:子查询的 id 为 2,外层查询 id 为 1,则先执行子查询。
  • id 混合(有相同也有不同):先执行 id 大的,id 相同的按顺序执行。

2. select_type:查询类型

区分普通查询、子查询、联合查询等,核心类型如下:

阅读全文 »

MySQL 锁机制全解析:类型、原理与实践

MySQL 的锁机制是保障并发场景下数据一致性的核心技术,通过合理的锁定策略协调多个事务对共享资源的访问。不同存储引擎的锁设计差异显著,理解锁的类型、粒度和算法,对优化并发性能、避免死锁至关重要。

锁的基本概念与作用

锁是数据库管理并发访问的规则,核心作用是控制多个事务对共享资源的有序访问,避免因并发操作导致的数据不一致(如脏读、不可重复读、幻读)。

  • 核心流程:事务修改数据前需获取锁 → 持有锁期间独占或共享资源 → 事务提交 / 回滚后释放锁。
  • 设计目标:在 “数据一致性” 和 “并发性能” 之间找到平衡 —— 锁粒度越细,并发越高但开销越大;粒度越粗,开销越小但并发越低。

按锁粒度分类(核心分类方式)

锁的粒度决定了锁定资源的范围,MySQL 支持表锁、行锁和页锁三种粒度,不同存储引擎对锁的支持不同。

表锁(Table Lock):粒度最大,偏读场景

表锁是锁定整张表的机制,实现简单、开销小、无死锁,但并发度低(适合读多写少场景)。

支持的存储引擎:

MyISAM、Memory、CSV 等非事务引擎(InnoDB 也支持表锁,但默认用行锁)。

核心特性:
  • 开销小、加锁快:无需逐行判断,直接锁定整张表。
  • 无死锁:锁定顺序简单,不会出现循环等待。
  • 并发度低:写操作会阻塞所有读写,读操作会阻塞写操作。
锁类型与行为:

表锁分为读锁(共享锁,S 锁)写锁(排他锁,X 锁),规则如下:

阅读全文 »

MySQL 体系结构详解:分层设计与核心组件

MySQL 采用客户机 / 服务器(C/S)架构,通过清晰的分层设计实现高效的数据管理与交互。其体系结构可分为四大层:连接层服务层插件式存储引擎层存储层,每层各司其职,共同完成从客户端请求到数据存储 / 检索的全流程。

整体架构:客户机与服务器的协作

MySQL 的运行依赖两个核心程序:

  • 服务器程序(mysqld):运行在数据库所在服务器,负责监听网络请求、处理 SQL 命令、管理数据存储,并将结果返回给客户端。
  • 客户机程序:如 mysql 命令行工具、图形化工具(Navicat)或编程语言驱动(Python 的 pymysql),负责与服务器建立连接并发送 SQL 请求。

这种架构的优势在于:客户端与服务器可分离部署(跨机器 / 跨网络),服务器集中管理数据,确保一致性与安全性。

四大分层结构及核心组件

总体结构

连接层:客户端与服务器的桥梁

连接层是 MySQL 与外部交互的入口,负责建立和管理客户端与服务器的连接。

核心组件:
阅读全文 »