当前位置: 首页 > news >正文

MySQL复杂SQL性能优化实战:多表联查与子查询的高效方法

一、多表联查(JOIN Operations)

多表联查是通过 JOIN 操作将多个表中的数据组合起来,基于表之间的关联关系进行查询。

(一)连接的类型(JOIN Types)
  1. INNER JOIN(内连接/等值连接)

    • 作用返回两个表中连接字段值相等的所有行组合

    • 语法

      SELECT 列名列表
      FROM 表1
      [INNER] JOIN 表2 ON 表1.关联字段 = 表2.关联字段
      [WHERE 条件];
    • 示例:查询所有有订单的客户信息(假设 customers 表有 customer_idorders 表有 customer_id 外键)。

      SELECT c.customer_id, c.name, o.order_id, o.order_date
      FROM customers c
      INNER JOIN orders o ON c.customer_id = o.customer_id;
  2. LEFT [OUTER] JOIN(左外连接)

    • 作用返回左表的所有行,即使在右表中没有匹配的行。对于左表中存在而右表中没有匹配的行,右表相关的列将显示为 NULL

    • 语法

      SELECT 列名列表
      FROM 表1
      LEFT [OUTER] JOIN 表2 ON 表1.关联字段 = 表2.关联字段
      [WHERE 条件];
    • 示例:查询所有客户及其订单(包括没有下过单的客户)

      SELECT c.customer_id, c.name, o.order_id, o.order_date
      FROM customers c
      LEFT JOIN orders o ON c.customer_id = o.customer_id;
  3. RIGHT [OUTER] JOIN(右外连接)

    • 作用返回右表的所有行,即使在左表中没有匹配的行。对于右表中存在而左表中没有匹配的行,左表相关的列将显示为 NULL

    • 语法

      SELECT 列名列表
      FROM 表1
      RIGHT [OUTER] JOIN 表2 ON 表1.关联字段 = 表2.关联字段
      [WHERE 条件];
    • 示例:查询所有订单及其对应的客户信息(包括那些可能关联到无效客户的订单)。

      SELECT c.customer_id, c.name, o.order_id, o.order_date
      FROM customers c
      RIGHT JOIN orders o ON c.customer_id = o.customer_id;
  4. FULL [OUTER] JOIN(全外连接)

    • 作用返回左表和右表中的所有行。当某行在另一个表中没有匹配行时,则另一个表相关的列将显示为 NULL。如果两个表中有匹配的行,则进行连接

    • 语法(MySQL 不支持直接的 FULL OUTER JOIN,需用 UNION 模拟)

      SELECT 列名列表
      FROM 表1
      LEFT JOIN 表2 ON 表1.关联字段 = 表2.关联字段
      UNION [ALL]
      SELECT 列名列表
      FROM 表1
      RIGHT JOIN 表2 ON 表1.关联字段 = 表2.关联字段
      WHERE 表1.关联字段 IS NULL;
    • 示例:查询所有客户和所有订单(包括没有订单的客户和没有对应客户的订单)

      SELECT c.customer_id, c.name, o.order_id, o.order_date
      FROM customers c
      LEFT JOIN orders o ON c.customer_id = o.customer_id
      UNION
      SELECT c.customer_id, c.name, o.order_id, o.order_date
      FROM customers c
      RIGHT JOIN orders o ON c.customer_id = o.customer_id
      WHERE c.customer_id IS NULL;
  5. CROSS JOIN(交叉连接/笛卡尔积)

    • 作用:返回两个表中所有可能的行组合。结果集的行数是 表1行数 * 表2行数

    • 语法

      SELECT 列名列表
      FROM 表1
      CROSS JOIN 表2;
    • 示例:生成所有产品和所有尺寸的组合。

      SELECT p.product_name, s.size_name
      FROM products p
      CROSS JOIN sizes s;
(二)多表连接(Joining More Than Two Tables)

可以连续使用多个 JOIN 子句连接多个表。

  • 语法

    SELECT ...
    FROM 表1
    JOIN 表2 ON 条件
    JOIN 表3 ON 条件
    ...
    [WHERE ...];
  • 示例:查询订单的详细信息(客户名、订单日期、产品名、数量)。

    SELECT c.name, o.order_date, p.product_name, od.quantity
    FROM orders o
    JOIN customers c ON o.customer_id = c.customer_id
    JOIN order_details od ON o.order_id = od.order_id
    JOIN products p ON od.product_id = p.product_id;
(三)自连接(Self Join)

自连接是将表与其自身连接,常用于表示层次结构(如员工-经理关系、类别-父类别)。

  • 技巧:需要使用表别名(Alias)来区分同一个表的两个“实例”。

  • 示例:查询员工及其经理的名字。

    SELECT e1.employee_name AS Employee, e2.employee_name AS Manager
    FROM employees e1
    LEFT JOIN employees e2 ON e1.manager_id = e2.employee_id;
(四)自然连接(NATURAL JOIN)和 USING 子句
  • NATURAL JOIN:自动连接所有同名列。强烈不推荐使用,因为它依赖于列名匹配,不明确且容易出错。

    SELECT ... FROM table1 NATURAL JOIN table2;
  • USING 子句:当连接的两个表具有完全相同名称的关联字段时,可以用 USING 简化 ON

    SELECT c.customer_id, c.name, o.order_id, o.order_date
    FROM customers c
    JOIN orders o USING (customer_id);

二、子查询(Subqueries)

子查询是嵌套在另一个 SQL 查询(主查询)内部的查询,子查询的结果被外部查询使用。

(一)子查询的位置(Where Subqueries Can Be Used)
  • SELECT 子句(标量子查询)

  • FROM 子句(派生表/内联视图)

  • WHERE 子句(最常用)

  • HAVING 子句

  • INSERT / UPDATE / DELETE 语句的 VALUESSET 部分

(二)子查询的主要类型
  1. 标量子查询(Scalar Subquery)

    • 特点:返回单个值(一行一列)。

    • 用途:可以出现在任何期望单个值的地方(如 SELECT 列表、WHERE 条件中的比较运算符右侧)。

    • 示例:查询价格高于平均价格的产品。

      SELECT product_name, price
      FROM products
      WHERE price > (SELECT AVG(price) FROM products);
  2. 列子查询(Column Subquery)

    • 特点:返回单列多行。

    • 用途:常与 INANY/SOMEALL 运算符一起用在 WHEREHAVING 子句中。

    • 示例(IN):查询至少订购过一次“Coffee”产品的客户。

      SELECT customer_id, name
      FROM customers
      WHERE customer_id IN (SELECT DISTINCT o.customer_idFROM orders oJOIN order_details od ON o.order_id = od.order_idJOIN products p ON od.product_id = p.product_idWHERE p.product_name = 'Coffee'
      );
  3. 行子查询(Row Subquery)

    • 特点:返回单行多列。

    • 用途:与行比较运算符一起使用

http://www.lryc.cn/news/578134.html

相关文章:

  • 【数据清洗与预处理】-文本采集与处理
  • LoRA 问答微调与部署全流程:基于 LLaMA-Factory + DeepSeek + FastAPI 打造专属大模型
  • Hive SQL 实战:电商销售数据分析全流程案例
  • 大数据轻量化流批一体架构探索实践(一)
  • 【数据分析】环境数据降维与聚类分析教程:从PCA到可视化
  • [特殊字符]【联邦学习实战】用 PyTorch 从 0 搭建一个最简单的联邦学习系统(含完整代码)
  • ubuntu下免sudo执行docker
  • spring-ai-alibaba官方 Playground 示例
  • 根据OS自动加载不同的native库和本地jar包
  • Ollama 深度使用指南:在本地玩转大型语言模型
  • 关于Spring的那点事(1)
  • AIGC检测系统升级后的AI内容识别机制与系统性降重策略研究(三阶段降重法)
  • 04_MySQL 通过 Docker 在同一个服务器上搭建主从集群(一主一从)
  • Junit_注解_枚举
  • 【区块链安全】代理合约中的漏洞
  • 【C++指南】C++ list容器完全解读(三):list迭代器的实现与优化
  • 【软考高项论文】论信息系统项目的成本管理
  • 渗透测试的重要性及最佳实践
  • 对selenium进行浏览器和驱动进行配置Windows | Linux
  • 调试W5500(作为服务器)
  • 淘宝API接口在数据分析中的应用
  • 非常详细版: dd.device.geolocation 钉钉微应用获取定位,移动端 PC端都操作,Vue实现钉钉微应用获取精准定位并渲染在地图组件上
  • 如何解决 Rider 编译输出乱码
  • leetcode:693. 交替位二进制数(数学相关算法题,python3解法)
  • Deepoc 大模型:无人机行业的智能变革引擎
  • Linux进程单例模式运行
  • 【AI News | 20250630】每日AI进展
  • 华为云Flexus+DeepSeek征文 | 从零开始搭建Dify-LLM应用开发平台:华为云全流程单机部署实战教程
  • 本地部署kafka4.0
  • Serverless 架构入门与实战:AWS Lambda、Azure Functions、Cloudflare Workers 对比