Firebird 2.5中如何删除员工单日仅一条记录的数据库条目?
Firebird 2.5 优化删除员工单日单条记录的SQL脚本
原脚本通过逐行子查询统计记录数,数据量较大时会因重复扫描全表导致卡顿,以下是两种更高效的优化方案:
方案一:GROUP BY预统计+NOT EXISTS关联删除
DELETE FROM my_table t1 WHERE NOT EXISTS ( SELECT 1 FROM my_table t2 GROUP BY t2.employee, t2.entry_date HAVING COUNT(*) > 1 AND t1.employee = t2.employee AND t1.entry_date = t2.entry_date )
- 逻辑:先一次性统计出所有员工单日记录数大于1的(员工,日期)组合,再筛选出不在这些组合内的记录进行删除,大幅减少表扫描次数。
方案二:临时表存储待删ID+批量删除(适合超大数据表)
如果数据表有主键(假设主键为id),可通过临时表批量处理,降低锁表时长:
-- 创建临时表存储待删除记录的主键ID CREATE GLOBAL TEMPORARY TABLE temp_delete_ids ( rec_id INTEGER PRIMARY KEY ) ON COMMIT DELETE ROWS; -- 筛选出需要删除的记录ID并插入临时表 INSERT INTO temp_delete_ids (rec_id) SELECT t1.id FROM my_table t1 LEFT JOIN ( SELECT employee, entry_date FROM my_table GROUP BY employee, entry_date HAVING COUNT(*) > 1 ) t2 ON t1.employee = t2.employee AND t1.entry_date = t2.entry_date WHERE t2.employee IS NULL; -- 批量删除目标记录 DELETE FROM my_table WHERE id IN (SELECT rec_id FROM temp_delete_ids);
- 逻辑:先把待删记录的主键存入临时表,再批量删除,避免长时间锁表,同时减少重复计算。
注意事项
- 操作前必须备份数据表,防止误删数据
- 若表无主键,可使用
(employee, entry_date, entry_value)组合作为唯一标识(需确保同员工同日期下录入值不重复) - 执行删除前,可将
DELETE替换为SELECT *验证待删记录是否符合预期
内容的提问来源于stack exchange,提问作者Roma Romanovas
相关产品推荐
相关产品推荐

