You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

同表Inner Join查询优化:避免重复使用IN子句的方法

SQL查询优化:避免重复IN子句的关联筛选

首先是数据表结构与测试数据:

CREATE TABLE my_table (
  id INTEGER PRIMARY KEY,
  key BOOLEAN NOT NULL
);

INSERT INTO my_table VALUES (10, true);
INSERT INTO my_table VALUES (11, true);
INSERT INTO my_table VALUES (12, true);
INSERT INTO my_table VALUES (20, false);
INSERT INTO my_table VALUES (21, false);

需求是筛选出包含id为11或12的关联记录(关联规则为:同key值且my_table_1.id < my_table_2.id)。最初的解决方案通过在JOIN条件中重复使用IN子句实现了正确结果,但当业务中需要匹配的id数量达到上万条时,重复的长IN列表会引发性能问题。

优化方案1:使用CTE(公共表表达式)存储目标id集合

通过CTE一次性定义需要匹配的id列表,后续只需引用该集合即可,避免重复编写IN子句:

WITH target_ids AS (
    -- 可直接替换为业务场景下的id查询语句,比如 SELECT id FROM business_table WHERE ...
    SELECT unnest(ARRAY[11, 12]) AS id
)
SELECT t1.id, t1.key, t2.id, t2.key
FROM my_table t1
INNER JOIN my_table t2 
    ON t1.id < t2.id
    AND t1.key = t2.key
WHERE EXISTS (
    SELECT 1 FROM target_ids ti WHERE ti.id IN (t1.id, t2.id)
);

优化方案2:使用临时表存储目标id集合(适合大数量id场景)

当目标id数量极大时,临时表配合主键索引能显著提升匹配效率:

-- 创建临时表并插入目标id
CREATE TEMPORARY TABLE target_ids (id INT PRIMARY KEY);
INSERT INTO target_ids VALUES (11), (12);
-- 批量导入时推荐用 COPY 命令提升效率

-- 执行查询
SELECT t1.id, t1.key, t2.id, t2.key
FROM my_table t1
INNER JOIN my_table t2 
    ON t1.id < t2.id
    AND t1.key = t2.key
WHERE EXISTS (
    SELECT 1 FROM target_ids ti WHERE ti.id = t1.id OR ti.id = t2.id
);

优化说明

两种方案都只需要定义一次目标id集合,避免了重复IN子句带来的冗余和性能损耗:

  • CTE写法简洁,适合中小规模的id列表;
  • 临时表配合索引能快速完成大规模id的匹配,执行效率更高。

另外,原查询中放在JOIN条件里的筛选逻辑,移至WHERE子句后效果完全一致,可读性更强。

内容的提问来源于stack exchange,提问作者Michael Linker

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.15 18:47:20