MySQL多表查询核心指南

MySQL多表查询核心指南

一、多表关系与ER模型

1. 关系类型与实现方案

关系类型 实现方式 经典案例
多对多 独立关联表+双外键 学生选课系统
一对多 多的一方添加外键 部门-员工关系
一对一 任意一方添加UNIQUE约束外键 用户基础信息-详情表拆分

二、连接查询全解析

1. 七种JOIN操作可视化

2. 核心查询类型详解

/* 隐式内连接(WHERE过滤)*/
SELECT e.name, d.name 
FROM emp e, dept d 
WHERE e.dept_id = d.id;

/* 显式左外连接(保留左表全部记录)*/
SELECT e.*, d.name 
FROM emp e 
LEFT JOIN dept d ON e.dept_id = d.id;

/* 全外连接实现(MySQL兼容方案)*/
(SELECT * FROM emp LEFT JOIN dept ON emp.dept_id = dept.id)
UNION
(SELECT * FROM emp RIGHT JOIN dept ON emp.dept_id = dept.id);

3. 自连接场景实践

/* 员工-领导层级查询 */
SELECT worker.name AS 员工,
       manager.name AS 直属领导,
       super_mgr.name AS 上级领导
FROM emp worker
LEFT JOIN emp manager ON worker.manager_id = manager.id
LEFT JOIN emp super_mgr ON manager.manager_id = super_mgr.id;

三、子查询深度优化

1. 四种子查询类型对比

«interface»
SubQuery
+execute()
ScalarQuery
单值结果
=, > 比较运算符
ColumnQuery
列结果
IN, ANY, ALL
RowQuery
行结构
多列匹配
TableQuery
临时表
JOIN操作

2. 典型应用案例

/* 标量子查询(部门最高薪)*/
SELECT name, salary
FROM emp 
WHERE salary = (
    SELECT MAX(salary) 
    FROM emp 
    WHERE dept_id = 2
);

/* EXISTS替代IN(存在订单的用户)*/
SELECT *
FROM users u
WHERE EXISTS (
    SELECT 1 
    FROM orders 
    WHERE user_id = u.id
);

/* 派生表联合查询(近三月数据聚合)*/
SELECT d.name, COUNT(*) 
FROM (
    SELECT * 
    FROM emp 
    WHERE entry_date > DATE_SUB(NOW(), INTERVAL 3 MONTH)
) AS new_emp
JOIN dept d ON new_emp.dept_id = d.id
GROUP BY d.name;

四、性能优化策略

1. 查询执行分析工具

0 1 2 3 4 5 6 7 8 9 10 语法解析 逻辑优化 物理执行 结果处理 查询执行流程

2. 优化清单手册

  1. 索引策略
  • 为所有JOIN字段添加索引(最左前缀原则)
  • WHERE条件列使用复合索引
  1. 改写技巧
  • 用BETWEEN代替双条件比较
  • 将OR转换为UNION查询
  • 使用LIMIT分页优化
  1. 危险操作
  • 禁止在WHERE中使用函数计算:
    /* 错误示例 */
    WHERE YEAR(create_time) = 2023
    
    /* 正确写法 */
    WHERE create_time BETWEEN '2023-01-01' AND '2023-12-31'
    
  1. 最佳实践
  • 单次查询JOIN表不超过3个
  • 批量处理代替循环单条操作
  • NULL判断使用IS NULL替代= NULL

速查表总结

问题类型 推荐解决方案
多表关联过滤 显式INNER JOIN + WHERE
保留未匹配记录 LEFT/RIGHT JOIN
层级关系查询 自连接+递归CTE(MySQL 8.0+)
存在性验证 EXISTS替代IN
分页优化 使用游标代替OFFSET
大数据量统计 物化视图+定期刷新

你可能感兴趣的:(SQL,mysql,数据库)