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

SQL非唯一条件去重:cc_index表URL单条保留需求及性能问询

问题1:修改查询实现每个url仅保留符合条件的一行

假设你现有的查询是通过子查询找到每个url的最大length后关联原表,这种方式会在同一url存在多个最大length行时返回多行。可以用**窗口函数ROW_NUMBER()**来精准筛选符合要求的行,这是最简洁高效的方案:

SELECT *
FROM (
    SELECT 
        *,
        -- 按url分组,先按length降序,再按date降序编号
        ROW_NUMBER() OVER (
            PARTITION BY url 
            ORDER BY length DESC, date DESC
        ) AS row_num
    FROM cc_index
) filtered
WHERE row_num = 1;

逻辑说明:

  • PARTITION BY url:将数据按url分组,每组单独处理
  • ORDER BY length DESC, date DESC:组内先按length从大到小排序,length相同则按date从新到旧排序
  • ROW_NUMBER():给每组的行分配唯一编号,排序最靠前的行编号为1,最终筛选出编号为1的行就是每个url的目标数据

如果你的数据库不支持窗口函数(比如旧版本MySQL),可以用关联子查询实现:

SELECT c.*
FROM cc_index c
INNER JOIN (
    SELECT 
        url,
        MAX(length) AS max_length,
        -- 先找到每个url的最大length,再在这些行里找最新的date
        MAX(date) AS max_date
    FROM cc_index
    WHERE (url, length) IN (
        SELECT url, MAX(length) FROM cc_index GROUP BY url
    )
    GROUP BY url
) t 
ON c.url = t.url 
AND c.length = t.max_length 
AND c.date = t.max_date;

问题2:无需关注date时,能否大幅提升查询性能?

通常可以提升性能,具体提升幅度取决于数据量和索引情况:

性能提升的原因:

  1. 减少排序开销:原本需要按length DESC, date DESC双字段排序,现在仅需按length DESC单字段排序,排序计算量减少;如果用数据库特定函数(如MySQL的ANY_VALUE),甚至可以完全避免排序。
  2. 更高效的查询写法:以MySQL为例,直接用GROUP BY结合MAX()和ANY_VALUE:
SELECT 
    url,
    MAX(length) AS length,
    ANY_VALUE(date) AS date,
    ANY_VALUE(其他列名) AS 其他列名
FROM cc_index
GROUP BY url;

这种写法不需要子查询和窗口函数的额外计算,直接分组取最大length,其他列取任意值,执行效率远高于窗口函数方案。
3. 索引优化空间更大:创建(url, length)的复合索引后,数据库可以直接通过索引快速定位每个url的最大length行,无需全表扫描,性能提升显著。

注意:

不同数据库对这类场景的优化语法不同,比如PostgreSQL可以用DISTINCT ON(同样高效):

SELECT DISTINCT ON (url) *
FROM cc_index
ORDER BY url, length DESC;

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.09 16:18:12