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

我的SQL DELETE语句中的子查询会多次执行吗?该如何优化?

关于你的DELETE语句子查询执行次数及修复方案

子查询是否会逐行执行?

你写的这个子查询是标量子查询(仅返回单个patient_id值),主流SQL引擎(包括你使用的练习平台)都会将其优化为仅执行一次,不会针对patients表的每一行重复运行。它会先计算出偏移10条后的第一个patient_id,再用这个值作为条件执行删除操作。

数据删除导致子查询结果变化的问题?

你的原语句其实不会出现这个问题——子查询的结果在DELETE执行前就已经确定,删除过程中不会重新计算这个临界值。不过原语句存在一个潜在风险:如果patient_id存在重复值,会误删本应保留的行(比如第10条和第11条的patient_id相同,>=条件会把第10条也删掉)。

修复方案

方案1:用窗口函数精准保留前N行

通过ROW_NUMBER()窗口函数标记行号,只保留行号≤10的记录,避免id重复带来的误删问题:

DELETE FROM patients
WHERE patient_id NOT IN (
    SELECT patient_id
    FROM (
        SELECT patient_id, ROW_NUMBER() OVER (ORDER BY patient_id) AS row_num
        FROM patients
    ) AS ranked_patients
    WHERE row_num <= 10
);

嵌套子查询是为了兼容部分不允许在DELETE语句中直接引用窗口函数的数据库。

方案2:用CTE(公共表表达式)简化写法

如果你的数据库支持CTE(比如PostgreSQL、MySQL 8.0+),可以用更清晰的逻辑实现:

WITH ranked_patients AS (
    SELECT patient_id, ROW_NUMBER() OVER (ORDER BY patient_id) AS row_num
    FROM patients
)
DELETE FROM patients
WHERE patient_id IN (
    SELECT patient_id FROM ranked_patients WHERE row_num > 10
);

这两种方案都会先一次性计算出所有要保留/删除的行,再执行删除操作,既避免了删除过程中数据变化影响结果的问题,也适配了patient_id重复的场景。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.20 20:33:33