文档标题位于omdok表中:
create table omdok ( dokumnr serial primary key, ... );
文档行位于omrid表中
CREATE TABLE omrid
(
id serial NOT NULL,
reanr serial NOT NULL,
dokumnr integer NOT NULL,
CONSTRAINT omrid_pkey PRIMARY KEY (id),
CONSTRAINT omrid_dokumnr_fkey FOREIGN KEY (dokumnr)
REFERENCES omdok (dokumnr) MATCH SIMPLE
ON UPDATE CASCADE ON DELETE CASCADE DEFERRABLE INITIALLY IMMEDIATE,
....
);
在omdok中没有omrid子行的记录需要删除
我试过
delete from omdok where dokumnr not in (select dokumnr from omrid)
查询它当前正在运行15个小时并且仍在运行。 postgres.exe一直使用50%的CPU(这是2核CPU)。
explain delete from omdok where dokumnr not in (select dokumnr from omrid)
返回:
"Delete (cost=0.00..21971079433.34 rows=220815 width=6)"
" -> Seq Scan on omdok (cost=0.00..21971079433.34 rows=220815 width=6)"
" Filter: (NOT (SubPlan 1))"
" SubPlan 1"
" -> Materialize (cost=0.00..94756.92 rows=1897261 width=4)"
" -> Seq Scan on omrid (cost=0.00..77858.61 rows=1897261 width=4)"
使用
PostgreSQL 9.0.1, compiled by Visual C++ build 1500, 64-bit
Windows 2003 x64 server with 4 GB RAM.
答案 0 :(得分:1)
您没有以任何方式限定DISTINCT
查询,因此将220,815个文档与1,897,261个文档行进行比较。这需要时间。
最简单的优化是在文档行上使用omrid
子句,这会使DELETE FROM omdok WHERE dokumnr NOT IN (SELECT DISTINCT dokumnr FROM omrid);
行的行数减少8倍左右:
WITH docs0rows AS (
SELECT dokumnr
FROM omdok d
LEFT JOIN (SELECT DISTINCT dokumnr FROM omrid) dr ON dr.dokumnr = d.dokumnr
WHERE dr.dokumnr IS NULL
)
DELETE FROM omdok d
USING docs0rows zero
WHERE d.dokumnr = zero.dokumnr;
一个可能更快的解决方案是首先识别没有行的文档,然后删除这些行:
Parent = {
name: 'Name',
age: 'Age',
children:
[{name: 'Name', age: 'Age'},
{name: 'Name', age: 'Age'},
{name: 'Name', age: 'Age'}]
}
免责声明:在运行此命令之前测试此命令以查看将删除哪些行。
答案 1 :(得分:0)
另一种方法是在omrid(dokumnr)
上简单地创建一个索引:
create index idx_omrid_dokumnr on omrid(dokumnr);
这可以加快原始查询中not in
的处理速度。