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

SQL优化咨询:如何规避SELECT*与冗余ROW_NUMBER列问题?

解决SQL排序取顶的性能与冗余列问题

作为SQL新手,你的两个担忧非常合理,咱们一步一步来解决:

问题1:SELECT * 的性能隐患

SELECT * 会读取表中所有列,哪怕你只需要其中几列,这会额外消耗磁盘IO和内存资源,尤其是当PROF_BID表有大量非必要列时,性能损耗会很明显。而且如果后续表结构发生变化(比如新增列),SELECT * 还可能导致插入时列数不匹配,引发报错。

问题2:冗余的ROW_NUMBER列

你的核心需求是用ROW_NUMBER()做分组过滤,但不需要把这个行号插入到目标表中。原来的写法因为用了SELECT *,把子查询里的行号也带进来了,咱们可以通过只选择需要的业务列来避免这个问题。

优化后的SQL写法

INSERT INTO FNL_PROF_BID_ID_W2 (CUST_ORD_NBR, STR_LOC_ID, PROF_BID_ID)
SELECT 
    sub.CUST_ORD_NBR, 
    sub.LOC_NBR AS STR_LOC_ID, 
    sub.PROF_BID_ID
FROM (
    SELECT 
        PB.CUST_ORD_NBR, 
        PB.LOC_NBR, 
        PB.PROF_BID_ID,
        -- 用别名rn存储行号,仅用于过滤
        ROW_NUMBER() OVER(
            PARTITION BY PB.CUST_ORD_NBR, PB.LOC_NBR 
            ORDER BY PB.PROF_BID_ID DESC, PB.CRT_TS DESC
        ) AS rn
    FROM PROF_BID PB
) sub
WHERE sub.rn = 1

优化点说明

  1. 替换SELECT*为明确列名:外层查询只选择目标表需要的CUST_ORD_NBR、LOC_NBR(映射为STR_LOC_ID)、PROF_BID_ID,避免读取冗余列,提升查询效率。
  2. 隔离行号列:子查询里给行号列起别名rn,仅用于WHERE条件过滤,外层不选择该列,自然不会插入到目标表中,解决冗余问题。

更易读的CTE写法(可选)

如果觉得子查询嵌套有点绕,用CTE(公共表表达式)可以让逻辑更清晰:

WITH ranked_bids AS (
    SELECT 
        PB.CUST_ORD_NBR, 
        PB.LOC_NBR, 
        PB.PROF_BID_ID,
        ROW_NUMBER() OVER(
            PARTITION BY PB.CUST_ORD_NBR, PB.LOC_NBR 
            ORDER BY PB.PROF_BID_ID DESC, PB.CRT_TS DESC
        ) AS rn
    FROM PROF_BID PB
)
INSERT INTO FNL_PROF_BID_ID_W2 (CUST_ORD_NBR, STR_LOC_ID, PROF_BID_ID)
SELECT CUST_ORD_NBR, LOC_NBR AS STR_LOC_ID, PROF_BID_ID
FROM ranked_bids
WHERE rn = 1

这两种写法都能满足你的需求,既解决了性能问题,又去掉了冗余的行号列,同时保证SQL逻辑正常运行。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.29 08:46:38