清理数据库垃圾数据时碰到的问题
有a表(主表)(id)
b表(从表)(id,aid)
寻找b表中和a表没关系的数据。在平时的操作中,经常删了a表数据,忘记删b表数据,因此造成b表中存在垃圾数据。开始写的语句select b.id from b where b.aid not in (select a.id from a)a表记录数大概100k,b表记录数大概1M。运行上面代码1分钟之后,我强制结束,找到0条记录。后来改进了一下select b.id from b left join a on b.aid=a.id where a.id is null
运行大概不到1秒钟便结束了,查询到1条数据。由此想了解一下left join 的工作原理

解决方案 »

  1.   

    子查询效率低于连接
    你用not in需要进行全表遍历
    你用这个比较一下
    select b.id from b where 
      not exists(select 1 from a where id=b.aid)
      

  2.   

    not in 的执行效率远低于not exists,子查询效率低于连接,能用连接尽量不用子查询。
      

  3.   

    看看tom的书
    比较执行计划
    select b.id from b where b.aid not in (select a.id from a where a.id is not null)
      

  4.   

    关于not in和not exists的性能你可以参考一下。http://blog.csdn.net/inthirties/archive/2009/08/26/4485630.aspx你这里可以试试这样的查询方式select b.id from b left join a on b.id = a.id where a.id is null
      

  5.   

    用not exists比较快。别用not in了
      

  6.   

    因为你的内表B有很多垃圾数据,整个数据比较多,你用的是关联子查询,b表是内表。in用的是hash join,所以内表如果小,整个查询的范围都会很小,如果内表很大,查询起来就很慢了。
      

  7.   

    清理数据库垃圾数据时碰到的问题 
    有a表(主表)(id) 
    b表(从表)(id,aid) 如果是图方便的话,可以在定义表的时候,标志为delete cascade
    alter table b
    add constraint fk_b_2_a foreign key(aid) references a(id) on delete cascade;这样删除主表的时候,会cascade了。
    现在你要清理的话,按上面朋友说的,提高性能就可以了