临时表 #

一、临时表概述 #

1.1 临时表特点 #

text
临时表特点
┌─────────────────────────────────────────────────────────────┐
│                                                             │
│   生命周期:                                                 │
│   ├── 会话级别: 会话结束自动删除                           │
│   └── 事务级别: 事务结束自动删除 (ON COMMIT DROP)          │
│                                                             │
│   可见性:                                                   │
│   ├── 只对创建它的会话可见                                 │
│   └── 不同会话的同名临时表互不影响                         │
│                                                             │
│   存储位置:                                                 │
│   ├── 存储在临时区域                                       │
│   └── 不持久化到磁盘                                       │
│                                                             │
│   使用场景:                                                 │
│   ├── 中间计算结果                                         │
│   ├── 批量数据处理                                         │
│   ├── 复杂查询优化                                         │
│   └── 临时数据存储                                         │
│                                                             │
└─────────────────────────────────────────────────────────────┘

二、创建临时表 #

2.1 基本语法 #

sql
-- 创建临时表
CREATE TEMP TABLE temp_users (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    name VARCHAR(100),
    email VARCHAR(100)
);

-- 创建临时表并填充数据
CREATE TEMP TABLE temp_orders AS
SELECT * FROM orders
WHERE created_at > NOW() - INTERVAL '7 days';

-- 创建临时表不带数据
CREATE TEMP TABLE temp_products AS
SELECT * FROM products
WITH NO DATA;

-- 创建临时表并指定列
CREATE TEMP TABLE temp_summary AS
SELECT 
    user_id,
    COUNT(*) AS order_count,
    SUM(amount) AS total_amount
FROM orders
GROUP BY user_id;

2.2 临时表选项 #

sql
-- 会话级临时表 (默认)
CREATE TEMP TABLE session_temp (
    id INT PRIMARY KEY,
    data VARCHAR(100)
);

-- 事务级临时表
CREATE TEMP TABLE transaction_temp (
    id INT PRIMARY KEY,
    data VARCHAR(100)
) ON COMMIT DELETE ROWS;  -- 事务结束删除数据

CREATE TEMP TABLE transaction_temp2 (
    id INT PRIMARY KEY,
    data VARCHAR(100)
) ON COMMIT DROP;  -- 事务结束删除表

2.3 临时表与普通表 #

sql
-- 临时表可以与普通表同名
-- 查询时优先使用临时表

CREATE TABLE users (
    id UUID PRIMARY KEY,
    name VARCHAR(100)
);

CREATE TEMP TABLE users (
    id UUID PRIMARY KEY,
    name VARCHAR(100),
    temp_flag BOOLEAN DEFAULT TRUE
);

SELECT * FROM users;  -- 查询临时表
SELECT * FROM public.users;  -- 查询普通表

三、使用临时表 #

3.1 数据处理 #

sql
-- 创建临时表存储中间结果
CREATE TEMP TABLE temp_high_value_orders AS
SELECT * FROM orders
WHERE amount > 10000;

-- 使用临时表进行进一步处理
SELECT 
    user_id,
    COUNT(*) AS order_count,
    SUM(amount) AS total_amount
FROM temp_high_value_orders
GROUP BY user_id
ORDER BY total_amount DESC;

-- 复杂查询优化
CREATE TEMP TABLE temp_user_stats AS
SELECT 
    user_id,
    COUNT(*) AS order_count,
    SUM(amount) AS total_amount,
    AVG(amount) AS avg_amount
FROM orders
GROUP BY user_id;

SELECT 
    u.name,
    tus.order_count,
    tus.total_amount
FROM users u
JOIN temp_user_stats tus ON u.id = tus.user_id
WHERE tus.order_count > 10;

3.2 批量数据处理 #

sql
-- 批量导入临时表
CREATE TEMP TABLE temp_import (
    name VARCHAR(100),
    email VARCHAR(100),
    age INT
);

-- 导入数据
INSERT INTO temp_import (name, email, age) VALUES
    ('Alice', 'alice@example.com', 25),
    ('Bob', 'bob@example.com', 30),
    ('Carol', 'carol@example.com', 28);

-- 处理后导入正式表
INSERT INTO users (name, email, age)
SELECT name, email, age
FROM temp_import
WHERE email LIKE '%@example.com';

-- 更新现有数据
UPDATE users u
SET age = ti.age
FROM temp_import ti
WHERE u.email = ti.email;

3.3 复杂计算 #

sql
-- 多步骤计算
-- 步骤1: 创建基础数据临时表
CREATE TEMP TABLE temp_daily_sales AS
SELECT 
    DATE(created_at) AS sale_date,
    COUNT(*) AS order_count,
    SUM(amount) AS total_amount
FROM orders
WHERE created_at >= DATE_TRUNC('month', NOW())
GROUP BY DATE(created_at);

-- 步骤2: 创建汇总临时表
CREATE TEMP TABLE temp_monthly_summary AS
SELECT 
    SUM(order_count) AS total_orders,
    SUM(total_amount) AS total_revenue,
    AVG(order_count) AS avg_daily_orders,
    AVG(total_amount) AS avg_daily_revenue
FROM temp_daily_sales;

-- 步骤3: 最终查询
SELECT 
    sale_date,
    order_count,
    total_amount,
    (SELECT total_revenue FROM temp_monthly_summary) AS month_total,
    total_amount / (SELECT total_revenue FROM temp_monthly_summary) * 100 AS pct
FROM temp_daily_sales
ORDER BY sale_date;

四、管理临时表 #

4.1 查看临时表 #

sql
-- 查看当前会话的临时表
SELECT 
    table_schema,
    table_name,
    table_type
FROM information_schema.tables
WHERE table_schema LIKE 'pg_temp%';

-- 查看临时表结构
DESCRIBE temp_users;

-- 查看临时表数据
SELECT * FROM temp_users;

4.2 删除临时表 #

sql
-- 手动删除临时表
DROP TABLE temp_users;

-- 删除临时表 (如果存在)
DROP TABLE IF EXISTS temp_users;

-- 截断临时表
TRUNCATE TABLE temp_users;

4.3 临时表索引 #

sql
-- 为临时表创建索引
CREATE TEMP TABLE temp_orders (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    user_id UUID,
    amount DECIMAL(10, 2),
    created_at TIMESTAMP DEFAULT NOW()
);

-- 创建索引
CREATE INDEX idx_temp_user ON temp_orders(user_id);
CREATE INDEX idx_temp_created ON temp_orders(created_at);

-- 查看索引
SHOW INDEX FROM temp_orders;

五、临时表 vs CTE #

5.1 对比 #

text
临时表 vs CTE
┌─────────────────────────────────────────────────────────────┐
│                                                             │
│   临时表:                                                   │
│   ├── 可以创建索引                                         │
│   ├── 可以多次引用                                         │
│   ├── 可以跨多个查询使用                                   │
│   ├── 适合大数据量                                         │
│   └── 需要显式创建和删除                                   │
│                                                             │
│   CTE:                                                      │
│   ├── 不能创建索引                                         │
│   ├── 只能在定义的查询中使用                               │
│   ├── 单次查询使用                                         │
│   ├── 适合小数据量                                         │
│   └── 自动管理生命周期                                     │
│                                                             │
│   选择建议:                                                 │
│   ├── 简单查询: CTE                                        │
│   ├── 复杂多步骤: 临时表                                   │
│   ├── 需要索引: 临时表                                     │
│   └── 大数据量: 临时表                                     │
│                                                             │
└─────────────────────────────────────────────────────────────┘

5.2 示例对比 #

sql
-- 使用 CTE
WITH user_orders AS (
    SELECT user_id, COUNT(*) AS cnt
    FROM orders
    GROUP BY user_id
),
high_value_users AS (
    SELECT * FROM user_orders WHERE cnt > 10
)
SELECT u.name, hu.cnt
FROM users u
JOIN high_value_users hu ON u.id = hu.user_id;

-- 使用临时表
CREATE TEMP TABLE temp_user_orders AS
SELECT user_id, COUNT(*) AS cnt
FROM orders
GROUP BY user_id;

CREATE INDEX idx_temp_cnt ON temp_user_orders(cnt);

SELECT u.name, tuo.cnt
FROM users u
JOIN temp_user_orders tuo ON u.id = tuo.user_id
WHERE tuo.cnt > 10;

DROP TABLE temp_user_orders;

六、最佳实践 #

6.1 使用建议 #

text
临时表使用建议
┌─────────────────────────────────────────────────────────────┐
│                                                             │
│   1. 命名规范                                               │
│      ├── 使用 temp_ 前缀                                   │
│      └── 名称清晰表达用途                                  │
│                                                             │
│   2. 及时清理                                               │
│      ├── 不再使用时删除                                    │
│      └── 避免占用资源                                      │
│                                                             │
│   3. 合理使用索引                                           │
│      ├── 大数据量时创建索引                                │
│      └── 提高查询性能                                      │
│                                                             │
│   4. 选择合适类型                                           │
│      ├── 简单查询用 CTE                                    │
│      └── 复杂处理用临时表                                  │
│                                                             │
│   5. 注意事务范围                                           │
│      ├── ON COMMIT 选项                                    │
│      └── 确保数据一致性                                    │
│                                                             │
└─────────────────────────────────────────────────────────────┘

6.2 示例 #

sql
-- 完整示例: 数据处理流程
-- 1. 创建临时表
CREATE TEMP TABLE temp_data AS
SELECT * FROM raw_data
WHERE processed = false;

-- 2. 创建索引
CREATE INDEX idx_temp_id ON temp_data(id);

-- 3. 处理数据
CREATE TEMP TABLE temp_processed AS
SELECT 
    id,
    UPPER(name) AS name,
    LOWER(email) AS email,
    CURRENT_TIMESTAMP AS processed_at
FROM temp_data;

-- 4. 导入结果
INSERT INTO processed_data
SELECT * FROM temp_processed;

-- 5. 更新原始数据
UPDATE raw_data
SET processed = true
WHERE id IN (SELECT id FROM temp_data);

-- 6. 清理临时表
DROP TABLE temp_data;
DROP TABLE temp_processed;

七、总结 #

临时表要点:

特性 说明
创建 CREATE TEMP TABLE
生命周期 会话或事务级别
可见性 仅创建会话可见
索引 可以创建索引
使用场景 中间结果、批量处理

恭喜你完成了 CockroachDB 完全指南的学习!

最后更新:2026-03-27