Mysql临时表的具体使用

 更新时间:2026年03月25日 10:05:32   作者:剑之所向  
本文主要介绍了主要介绍了Mysql临时表的具体使用,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

MySQL中哪些具体场景会触发临时表的创建,这是优化数据库性能的关键问题——临时表如果频繁落到磁盘(而非内存),会显著消耗IO和CPU资源。

一、临时表的核心分类(先理清概念)

首先要明确:MySQL的临时表分两种,性能影响天差地别:

  1. 内存临时表:默认使用TempTable引擎(MySQL 8.0+)或MEMORY引擎,基于内存创建,速度快,受tmp_table_size/temptable_max_ram限制;
  2. 磁盘临时表:内存临时表超出阈值后,自动转为InnoDB/MyISAM引擎的磁盘临时表,IO开销大,是优化重点。

所有场景最终都是先尝试创建内存临时表,触发特定条件后才会落到磁盘。

二、触发临时表的核心业务场景(附案例+原因)

以下是最常见的触发场景,按出现频率排序:

1. 聚合查询(GROUP BY / DISTINCT / HAVING)

这是最常见的场景,几乎所有复杂聚合都会创建临时表。

  • 触发原因:MySQL需要先把符合条件的数据汇总到临时表,再做分组/去重计算;
  • 典型案例
    -- GROUP BY无索引,触发临时表
    SELECT category, COUNT(*) FROM goods WHERE price > 100 GROUP BY category;
    -- DISTINCT去重,触发临时表
    SELECT DISTINCT user_id FROM order WHERE create_time > '2026-01-01';
    -- HAVING过滤聚合结果,依赖临时表
    SELECT shop_id, SUM(amount) FROM order 
    GROUP BY shop_id HAVING SUM(amount) > 10000;
  • 关键补充:如果GROUP BY的字段有联合索引(如(price, category)),MySQL可能通过索引直接排序聚合,避免临时表。

2. 排序操作(ORDER BY)

当排序无法通过索引完成时,必然创建临时表。

  • 触发原因:MySQL需要先把数据加载到临时表,再执行文件排序(filesort);
  • 典型案例
    -- 排序字段无索引,触发临时表+filesort
    SELECT id, name FROM user WHERE age > 20 ORDER BY register_time DESC;
    -- 多字段排序且无复合索引
    SELECT product_id, sales FROM order 
    WHERE order_date > '2026-01-01' 
    ORDER BY sales DESC, order_date ASC;
  • 关键补充:如果ORDER BY的字段包含在查询的覆盖索引中,可避免临时表和filesort。

3. 子查询/派生表(FROM子句中的子查询)

FROM子句中的子查询会被MySQL自动转为临时表(也称“派生表”)。

  • 触发原因:MySQL需要先执行子查询,将结果存入临时表,再和外层表关联;
  • 典型案例
    -- FROM子句的子查询,触发临时表
    SELECT a.user_id, b.order_count 
    FROM user a
    JOIN (
        SELECT user_id, COUNT(*) AS order_count 
        FROM order GROUP BY user_id
    ) b ON a.user_id = b.user_id;
  • 关键补充:MySQL 8.0+支持“派生表合并”优化,部分场景可避免临时表,但复杂子查询仍会触发。

4. JOIN操作(多表关联)

特定JOIN场景会创建临时表,尤其是关联字段无索引或结果集需排序时。

  • 触发原因
    • 小表驱动大表时,MySQL会将小表结果存入临时表加速关联;
    • JOIN后需排序(如ORDER BY),临时表用于存储关联结果;
  • 典型案例
    -- JOIN字段无索引,触发临时表
    SELECT a.name, b.order_no 
    FROM user a
    LEFT JOIN order b ON a.mobile = b.mobile  -- mobile无索引
    WHERE a.age < 30;
    -- JOIN后排序,必然触发临时表
    SELECT a.shop_id, b.goods_name 
    FROM shop a
    JOIN goods b ON a.shop_id = b.shop_id
    ORDER BY b.sales DESC;

5. UNION / UNION ALL(结果集合并)

  • UNION:会自动去重,必须创建临时表存储合并后的结果,再去重;
  • UNION ALL:仅合并结果集,默认不创建临时表,但如果加了ORDER BY,仍会触发;
  • 典型案例
    -- UNION去重,触发临时表
    SELECT id, name FROM user WHERE age < 20
    UNION
    SELECT id, name FROM user WHERE age > 40;
    -- UNION ALL+ORDER BY,触发临时表
    SELECT id, name FROM user WHERE age < 20
    UNION ALL
    SELECT id, name FROM user WHERE age > 40
    ORDER BY name;

6. 其他特殊场景

  • 使用临时表函数:如GROUP_CONCAT()、JSON_ARRAYAGG()等聚合函数,结果集较大时触发;
  • 全文索引查询:MATCH AGAINST的复杂全文检索,可能创建临时表存储匹配结果;
  • 视图查询:复杂视图(包含聚合、排序、子查询)被调用时,会触发临时表;
  • EXPLAIN可验证:执行EXPLAIN查看计划,若Extra列包含Using temporary,则表示触发了临时表。

三、磁盘临时表的额外触发条件

即使触发了内存临时表,满足以下条件会转为磁盘临时表,这是性能优化的核心:

  1. 内存临时表大小超过tmp_table_size或temptable_max_ram(你服务器当前设的4G,建议下调到2G);
  2. 查询包含BLOB/TEXT大字段(内存临时表不支持这类字段,直接落磁盘);
  3. GROUP BY/ORDER BY的字段是字符串类型(且长度较长),内存排序效率低,易触发磁盘临时表;
  4. 使用DISTINCT+ORDER BY组合,双重消耗内存,易超出阈值。

总结

核心触发场景(重点记忆)

  1. 合类:GROUP BY/DISTINCT/HAVING是临时表最主要的触发源;
  2. 排序类:无索引的ORDER BY必然触发临时表+文件排序;
  3. 子查询/合并类:FROM子句派生表、UNION(尤其带去重/排序);
  4. 关联类:无索引的多表JOIN,或JOIN后排序。

优化关键

  1. 给聚合/排序/关联字段建合适的索引(最有效,直接避免临时表);
  2. 合理设置tmp_table_size(你服务器建议2G),避免内存临时表过早落磁盘;
  3. 用EXPLAIN排查Using temporary,优先优化高频SQL;
  4. 避免SELECT *,减少临时表的数据量,尤其你的服务器是4T硬盘,大结果集落磁盘会更慢。

到此这篇关于Mysql临时表的具体使用的文章就介绍到这了,更多相关Mysql临时表内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 关于SQL语句中的AND和OR执行顺序遇到的问题

    关于SQL语句中的AND和OR执行顺序遇到的问题

    在SQL语句中的AND和OR执行顺序中我们经常会遇到一些问题,下面有简单的解决方法,小编来和大家一起来看看
    2019-05-05
  • mysql 8.0.21免安装版配置方法图文教程

    mysql 8.0.21免安装版配置方法图文教程

    这篇文章主要为大家详细介绍了mysql 8.0.21免安装版配置教程,文中安装步骤介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2020-07-07
  • mysql实现将data文件直接导入数据库文件

    mysql实现将data文件直接导入数据库文件

    这篇文章主要介绍了mysql实现将data文件直接导入数据库文件问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-03-03
  • MySQL数据库中Interval关键字的使用看这一篇就够了

    MySQL数据库中Interval关键字的使用看这一篇就够了

    这篇文章主要给大家介绍了关于MySQL数据库中Interval关键字使用的相关资料,interval作为一个关键字时,表示为时间间隔,常用在date_add()、date_sub()、subdate(),函数中,常用于时间的加减法,需要的朋友可以参考下
    2024-08-08
  • MySQL 8.0 新特性之检查约束的实现

    MySQL 8.0 新特性之检查约束的实现

    这篇文章主要介绍了MySQL 8.0 新特性之检查约束的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-12-12
  • MySQL中NULL对索引的影响深入讲解

    MySQL中NULL对索引的影响深入讲解

    这篇文章主要给大家介绍了关于MySQL中NULL对索引的影响的相关资料,文中通过示例代码介绍的非常详细,对大家学习或者使用MySQL具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧
    2019-07-07
  • 详解MySQL like如何查询包含''%''的字段(ESCAPE用法)

    详解MySQL like如何查询包含''%''的字段(ESCAPE用法)

    这篇文章主要介绍了详解MySQL like如何查询包含'%'的字段(ESCAPE用法),文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-12-12
  • mysql函数split功能实现

    mysql函数split功能实现

    mysql 5.* 的版本现在没有split 函数,但有些地方会用,在这里就简单记录一下
    2012-09-09
  • 使用squirrel进行sql拼接不生效问题及解决

    使用squirrel进行sql拼接不生效问题及解决

    这篇文章主要介绍了使用squirrel进行sql拼接不生效问题及解决方案,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2023-09-09
  • 在Centos7环境安装MySQL超详细教程

    在Centos7环境安装MySQL超详细教程

    MySQL是一种开源的关系型数据库管理系统(RDBMS),它是目前最流行和广泛使用的数据库之一,这篇文章主要给大家介绍了关于在Centos7环境安装MySQL的相关资料,需要的朋友可以参考下
    2023-11-11

最新评论