MySQL技术问题:筛选低评分唯一歌曲标题并规避专辑关联歌曲
嘿,针对你的需求,我整理了一套靠谱的方案,分查询验证和删除操作两步,还考虑了大数据库的性能问题:
先验证目标数据(删除前必做!)
首先你需要先确认哪些歌曲符合条件——评分低于3、标题唯一,且不在Albums表中。这里提供两种常用的查询方式,你可以根据自己的表结构选择:
方式1:使用NOT EXISTS(逻辑清晰,推荐)
SELECT DISTINCT m.Title FROM Music m WHERE m.Rating < 3 AND NOT EXISTS ( SELECT 1 FROM Albums a WHERE a.Title = m.Title -- 注意:如果你的Albums表是通过歌曲ID(比如SongID)关联的,替换成对应的字段,比如a.SongID = m.SongID );
方式2:使用LEFT JOIN
SELECT DISTINCT m.Title FROM Music m LEFT JOIN Albums a ON m.Title = a.Title -- 同样,关联字段根据实际表结构调整 WHERE m.Rating < 3 AND a.Title IS NULL;
执行删除操作
确认查询结果无误后,就可以删除这些低评分歌曲了。同样提供两种写法,并且针对9GB的大数据库,给你一些性能优化建议:
基础删除语句
用NOT EXISTS的写法:
DELETE m FROM Music m WHERE m.Rating < 3 AND NOT EXISTS ( SELECT 1 FROM Albums a WHERE a.Title = m.Title -- 关联字段和上面查询保持一致 );
用LEFT JOIN的写法:
DELETE m FROM Music m LEFT JOIN Albums a ON m.Title = a.Title WHERE m.Rating < 3 AND a.Title IS NULL;
大数据库性能优化技巧
因为你的数据库超过9GB,直接全表删除可能会锁表很久,影响业务,建议这么做:
- 添加索引:给
Music.Rating创建索引,能快速定位低评分记录;如果用Title关联,给Music.Title和Albums.Title也建索引(用ID关联的话就给ID字段建):CREATE INDEX idx_music_rating ON Music(Rating); -- 如果用Title关联,加这两个索引 CREATE INDEX idx_music_title ON Music(Title); CREATE INDEX idx_albums_title ON Albums(Title); - 分批删除:每次只删一部分数据,避免长时间锁表:
比如每次删1000条,重复执行直到没有符合条件的记录:
或者按主键范围分批(假设你有自增主键SongID):DELETE m FROM Music m WHERE m.Rating < 3 AND NOT EXISTS ( SELECT 1 FROM Albums a WHERE a.Title = m.Title ) LIMIT 1000;DELETE m FROM Music m WHERE m.SongID BETWEEN 1 AND 10000 -- 每次调整这个范围 AND m.Rating < 3 AND NOT EXISTS ( SELECT 1 FROM Albums a WHERE a.SongID = m.SongID ); - 选择低峰期执行:避开业务繁忙时段,减少对用户的影响
重要提醒
- 执行删除前一定要备份数据,或者先把查询结果导出保存,避免误删无法恢复
- 如果
Title不是歌曲的唯一标识(比如存在同名不同版本的歌曲),一定要用唯一主键(比如SongID)来关联Albums表,不然可能会误删不该删的歌曲
内容的提问来源于stack exchange,提问作者File
相关产品推荐
相关产品推荐

