X-Original-To: pgsql-performance-postgresql.org@localhost.postgresql.org Received: from localhost (unknown [200.46.204.144]) by svr1.postgresql.org (Postfix) with ESMTP id A630452C87 for ; Tue, 26 Jul 2005 16:02:25 -0300 (ADT) Received: from svr1.postgresql.org ([200.46.204.71]) by localhost (av.hub.org [200.46.204.144]) (amavisd-new, port 10024) with ESMTP id 33563-02 for ; Tue, 26 Jul 2005 19:02:15 +0000 (GMT) Received: from smtp-gw-cl-d.dmv.com (smtp-gw-cl-d.dmv.com [216.240.97.42]) by svr1.postgresql.org (Postfix) with ESMTP id BE67252C88 for ; Tue, 26 Jul 2005 16:02:12 -0300 (ADT) Received: from lanshark.dmv.com (lanshark.dmv.com [216.240.97.46]) by smtp-gw-cl-d.dmv.com (8.12.10/8.12.10) with ESMTP id j6QJ2ACf065855; Tue, 26 Jul 2005 15:02:10 -0400 (EDT) (envelope-from sven@dmv.com) Subject: Re: faster INSERT with possible pre-existing row? From: Sven Willenberger To: Dan Harris Cc: pgsql-performance@postgresql.org In-Reply-To: References: Content-Type: text/plain Date: Tue, 26 Jul 2005 15:03:17 -0400 Message-Id: <1122404597.1605.50.camel@lanshark.dmv.com> Mime-Version: 1.0 X-Mailer: Evolution 2.2.1.1 Content-Transfer-Encoding: 7bit X-Scanned-By: MIMEDefang 2.48 on 216.240.97.42 X-Virus-Scanned: by amavisd-new at hub.org X-Spam-Status: No, hits=0.329 tagged_above=0 required=5 tests=AWL, DNS_FROM_RFC_WHOIS X-Spam-Level: X-Archive-Number: 200507/397 X-Sequence-Number: 13638 On Tue, 2005-07-26 at 10:50 -0600, Dan Harris wrote: > I am working on a process that will be inserting tens of million rows > and need this to be as quick as possible. > > The catch is that for each row I could potentially insert, I need to > look and see if the relationship is already there to prevent > multiple entries. Currently I am doing a SELECT before doing the > INSERT, but I recognize the speed penalty in doing to operations. I > wonder if there is some way I can say "insert this record, only if it > doesn't exist already". To see if it exists, I would need to compare > 3 fields instead of just enforcing a primary key. > > Even if this could be a small increase per record, even a few percent > faster compounded over the whole load could be a significant reduction. > > Thanks for any ideas you might have. > Perhaps a trigger: CREATE FUNCTION verify_unique() RETURNS TRIGGER AS $func$ BEGIN PERFORM a,b,c FROM table1 WHERE a = NEW.a and b = NEW.b and c = NEW.c; IF FOUND THEN RETURN NULL; END IF; RETURN NEW; END; $func$ LANGUAGE plpgsql STABLE; CREATE TRIGGER verify_unique BEFORE INSERT ON table1 FOR EACH ROW EXECUTE PROCEDURE verify_unique(); Triggers are fired on COPY commands and if table1 is able to be cached and you have an index on table1(a,b,c) the results should be fairly decent. I would be interested in seeing the difference in timing between this approach and the temp table approach.