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

PostgreSQL 14.6:按校获取指定数量学生最新身份证高效查询

高效查询方案:按学校限制取最新学生的最新身份证

核心需求拆解

  • 针对指定的多所学校,每校最多返回100个最新加入学生的最新身份证
  • 保证查询性能,适配每校200~20000学生的规模

方案一:先筛选目标学生,再取对应最新身份证(推荐)

利用窗口函数先过滤出每校前100名最新加入的学生(依赖school_students.id自增特性,id越大代表加入时间越晚),再关联身份证表取每个学生的最新身份证:

WITH top_students AS (
    SELECT 
        ss.id AS school_student_id,
        ss.school_id
    FROM school_students ss
    WHERE ss.school_id IN ('1', '2', '3') -- 替换为应用层传入的school_ids列表,注意是字符串类型
    QUALIFY ROW_NUMBER() OVER (PARTITION BY ss.school_id ORDER BY ss.id DESC) <= 100
)
SELECT MAX(c.id) AS id_card_id
FROM id_cards c
JOIN top_students ts ON c.school_student_id = ts.school_student_id
GROUP BY ts.school_id, ts.school_student_id;

注:如果使用PostgreSQL 12及以下版本,不支持QUALIFY语法,可改用子查询实现:

WITH top_students AS (
    SELECT 
        ss.id AS school_student_id,
        ss.school_id
    FROM (
        SELECT 
            ss.*,
            ROW_NUMBER() OVER (PARTITION BY ss.school_id ORDER BY ss.id DESC) AS rn
        FROM school_students ss
        WHERE ss.school_id IN ('1', '2', '3')
    ) ss
    WHERE ss.rn <= 100
)
SELECT MAX(c.id) AS id_card_id
FROM id_cards c
JOIN top_students ts ON c.school_student_id = ts.school_student_id
GROUP BY ts.school_id, ts.school_student_id;

方案二:先取所有学生最新身份证,再按学校筛选前100

先计算所有目标学校学生的最新身份证,再通过窗口函数限制每校返回数量:

WITH student_latest_idcard AS (
    SELECT 
        ss.school_id,
        ss.id AS school_student_id,
        MAX(c.id) AS id_card_id
    FROM id_cards c
    JOIN school_students ss ON c.school_student_id = ss.id
    WHERE ss.school_id IN ('1', '2', '3')
    GROUP BY ss.school_id, ss.id
),
top_idcards AS (
    SELECT id_card_id
    FROM (
        SELECT 
            *,
            ROW_NUMBER() OVER (PARTITION BY school_id ORDER BY school_student_id DESC) AS rn
        FROM student_latest_idcard
    ) t
    WHERE rn <= 100
)
SELECT id_card_id FROM top_idcards;

性能优化:添加针对性索引

为了让窗口函数和关联查询高效执行,建议添加以下两个索引:

  1. 加速school_students按学校分组取最新学生的查询:
CREATE INDEX idx_school_students_school_id_id_desc ON school_students(school_id, id DESC);

这个索引可以让数据库直接按school_id分组,按id降序快速取前100条,避免全表扫描和排序。

  1. 加速id_cards获取每个学生最新身份证的查询:
CREATE INDEX idx_id_cards_school_student_id_id_desc ON id_cards(school_student_id, id DESC);

通过这个索引,数据库可以直接定位到每个school_student_id对应的最大id(最新身份证),不需要扫描该学生的所有身份证记录。

性能对比

  • 方案一优先筛选出少量目标学生(每校100),再关联身份证表,处理的数据量更小,在学校学生数较多时性能更优。
  • 方案二先处理所有目标学校的学生数据,再筛选,适合学校学生数较少的场景,但整体性能略逊于方案一。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.08 07:30:08