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

如何高效实现表级Either-Or查询并优化执行性能

最优实现方案及性能优化建议

方案1:使用EXISTS实现Either-Or逻辑(性能最优)

该方案无需重复执行Parent表关联逻辑,且EXISTS自带短路求值特性,只要满足Son或Daughter任意一个条件就会停止校验,不会产生冗余计算,同时关联时可以直接命中Son和Daughter表的Pid索引,先通过Pid过滤再校验低区分度的wearing_glass条件,大幅减少待校验数据量。

SELECT p.*
FROM (
    SELECT Pid, ...
    FROM Parent 
    JOIN Foreign1 ON ...
    LEFT JOIN Foreign2 ON ...
) p
WHERE 
    EXISTS (
        SELECT 1 FROM Son s 
        WHERE s.Pid = p.Pid AND s.son_wearing_glass
    )
    OR
    EXISTS (
        SELECT 1 FROM Daughter d 
        WHERE d.Pid = p.Pid AND d.daughter_wearing_glass
    );

如果需要去重(同一个Pid同时满足Son和Daughter条件时只返回一次),该写法天然支持,不需要额外加UNION/ DISTINCT。

方案2:CTE复用Parent关联结果(适合需要保留UNION ALL逻辑的场景)

如果你的业务逻辑更适合拆分Son和Daughter的关联逻辑,可以用CTE缓存Parent关联后的结果,避免两次重复执行p子查询:

WITH parent_filtered AS (
    SELECT Pid, ...
    FROM Parent 
    JOIN Foreign1 ON ...
    LEFT JOIN Foreign2 ON ...
)
SELECT p.* FROM parent_filtered p
JOIN Son s ON p.Pid = s.Pid WHERE s.son_wearing_glass
UNION ALL
SELECT p.* FROM parent_filtered p
JOIN Daughter d ON p.Pid = d.Pid WHERE d.daughter_wearing_glass;

如果需要去重,把UNION ALL改成UNION即可。

额外索引优化(可让性能再提升1~2个数量级)

针对低区分度的wearing_glass条件,你可以给Son和Daughter表建联合索引,关联和条件校验都可以直接走索引覆盖,无需回表:

-- Son表联合索引:先通过Pid定位,直接在索引中判断wearing_glass条件
CREATE INDEX idx_son_pid_wearing ON Son(Pid, son_wearing_glass);
-- Daughter表联合索引
CREATE INDEX idx_daughter_pid_wearing ON Daughter(Pid, daughter_wearing_glass);

方案对比

  1. 最初的写法:先全表扫Son/Daughter的wearing_glass条件,返回大量低区分度结果后再和Parent关联,无效计算多,性能最差
  2. 拆分UNION ALL重复执行p子查询的写法:关联逻辑高效但Parent关联重复计算,资源消耗翻倍
  3. 上述EXISTS方案:兼具关联效率和无冗余计算的优势,是当前场景的最优解

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 14:15:06