SQL:如何查找未使用的主键

时间:2011-03-22 08:48:55

标签: sql performance primary-key

我有一张带>的桌子1'000'000个条目;此表从大约130个其他表中引用。我的问题是很多这些1-mio条目都是旧的和未使用的。

找到未被任何其他表引用的条目的紧固方法是什么?我不喜欢做

select * from (
select * from table-a TA
minus
select * from table-a TA where TA.id in (
select "ID" from (
   (select distinct FK-ID "ID" from table-b)
union all
  (select distinct FK-ID "ID" from table-c)
...

是否有更简单,更通用的方式?

谢谢大家!

5 个答案:

答案 0 :(得分:7)

你可以这样做:

select * from table_a a
 where not exists (select * from table_b where fk_id = a.id)
   and not exists (select * from table_c where fk_id = a.id)
   and not exists (select * from table_d where fk_id = a.id)
   ...

答案 1 :(得分:0)

尝试:

select a.* 
from table_a a
left join table_b b on a.id=b.fk_id
left join table_c c on a.id=c.fk_id
left join table_d d on a.id=d.fk_id
left join table_e e on a.id=e.fk_id
......
where b.fk_id is null 
and c.fk_id is null 
and d.fk_id is null 
and e.fk_id is null 
.....

您也可以尝试:

select a.* 
from table_a a
left join
    (select b.fk_id from table_b b union
     select c.fk_id from table_c c union
     ...) table_union on a.id=table_union.fk_id
where table_union.fk_id is null

这更像是面向SQL,它不会像上面的解决方案那样永远。

答案 2 :(得分:0)

不确定效率,但是:

select * from table_a 
where id not in ( 
    select id from table_b
    union
    select id from table_c )

如果您关注的是允许数据库继续正常操作,而您可以将其分成多个阶段:

insert into tblIds 
    select id from table_a
    union
    select id from table_b

根据您的需要,然后:

delete * from table_a where id not in ( select id from tableIds )

当然,有时候进行大量处理需要花费很多时间。

答案 3 :(得分:0)

我喜欢上面@ Patrick的回答,但我想补充一点 您可以通过扫描sysObjects,查找关键关系并生成INSERT语句来构建这些INSERT语句,而不是手动构建130步查询。

这不仅可以节省您的时间,还可以帮助您确定您是否覆盖了所有表格 - 可能有131个,或者只有129个。

答案 4 :(得分:0)

我倾向于Marcelo Cantos的回答(并且已经赞成它),但是这里有一个替代方案,试图避免在外键上没有索引的问题......

WITH
  ids_a AS
(
  SELECT id FROM myTable
)
,
  ids_b AS
(
  SELECT id FROM ids_a WHERE NOT EXISTS (SELECT * FROM table_a WHERE fk_id = ids_a.id)
)
,
  ids_c AS
(
  SELECT id FROM ids_b WHERE NOT EXISTS (SELECT * FROM table_b WHERE fk_id = ids_b.id)
)
,
...
,
  ids_z AS
(
  SELECT id FROM ids_y WHERE NOT EXISTS (SELECT * FROM table_y WHERE fk_id = ids_y.id)
)

SELECT * FROM ids_z

我所要做的就是向甲骨文建议订购,以尽量减少其努力。不幸的是,Oracle会将其编译为非常类似于Marcelo Cantos的答案,并且它可能不会有任何不同的表现。