在关系型数据库中,临时表(Temporary Table)常用于拆分复杂查询、缓存中间结果、减少重复计算。合理使用可以显著提升性能,但用不好反而会成为瓶颈。下面从什么时候用、怎么建、怎么用、以及优化技巧几个维度说明。
✅ 适合场景:
❌ 不适合场景:
❌ 错误:
SELECT * INTO #tmp FROM orders;
✅ 正确:
SELECT order_id, user_id, amount
INTO #tmp
FROM orders
WHERE create_time >= '2024-01-01';
➡ 减少 IO、内存、后续排序成本
临时表默认没有索引,大表会全表扫描。
CREATE INDEX ix_tmp_user ON #tmp(user_id);
或(MySQL):
CREATE TEMPORARY TABLE tmp (
id INT,
user_id INT,
INDEX ix_user(user_id)
);
✅ 在以下情况一定要加索引:
❌:
INSERT INTO #tmp SELECT * FROM big_table;
✅:
INSERT INTO #tmp
SELECT *
FROM big_table
WHERE status = 1
AND date > '2024-01-01';
➡ 临时表越小,后续越快
| 方案 | 适用场景 | 性能特点 |
|---|---|---|
| 临时表 | 多次使用中间结果 | 可控、可加索引 |
| CTE(WITH) | 一次性、逻辑清晰 | 不一定物化 |
| 子查询 | 简单场景 | 可能被重复执行 |
| 表变量 | 小数据量 | 内存为主 |
| 物理表 | 跨会话/长期 | IO 成本高 |
CREATE TEMPORARY TABLE tmp ENGINE=MEMORY ...
tmp_table_size#temp 局部临时表优于 @tableOPTION (RECOMPILE) 解决参数嗅探ON COMMIT PRESERVE ROWSSELECT *
FROM orders o
WHERE user_id IN (
SELECT user_id FROM vip_users
)
AND order_id IN (
SELECT order_id FROM big_log
);
SELECT user_id INTO #vip FROM vip_users;
CREATE INDEX ix ON #vip(user_id);
SELECT order_id INTO #log FROM big_log;
CREATE INDEX ix2 ON #log(order_id);
SELECT o.*
FROM orders o
JOIN #vip v ON o.user_id = v.user_id
JOIN #log l ON o.order_id = l.order_id;
✅ 执行计划更稳定,IO 明显减少
如果你能告诉我:
我可以帮你针对性优化某条查询。
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。