Received: from localhost (maia-4.hub.org [200.46.204.183]) by postgresql.org (Postfix) with ESMTP id 52C8A9F9F0A for ; Tue, 22 May 2007 07:01:05 -0300 (ADT) Received: from postgresql.org ([200.46.204.71]) by localhost (mx1.hub.org [200.46.204.183]) (amavisd-maia, port 10024) with ESMTP id 21786-01 for ; Tue, 22 May 2007 07:01:00 -0300 (ADT) X-Greylist: from auto-whitelisted by SQLgrey-1.7.5 Received: from floppy.pyrenet.fr (floppy.pyrenet.fr [194.116.145.2]) by postgresql.org (Postfix) with ESMTP id D45EB9FA161 for ; Tue, 22 May 2007 07:00:59 -0300 (ADT) Received: by floppy.pyrenet.fr (Postfix, from userid 106) id 395EE30B2B; Tue, 22 May 2007 12:00:58 +0200 (MET DST) From: valgog X-Newsgroups: pgsql.performance Subject: Re: Key/Value reference table generation: INSERT/UPDATE performance Date: 22 May 2007 03:00:41 -0700 Organization: http://groups.google.com Lines: 37 Message-ID: <1179828041.761272.152380@x35g2000prf.googlegroups.com> References: <1179822183.740891.271130@n59g2000hsh.googlegroups.com> Mime-Version: 1.0 Content-Type: text/plain; charset="iso-8859-1" X-Complaints-To: groups-abuse@google.com In-Reply-To: <1179822183.740891.271130@n59g2000hsh.googlegroups.com> User-Agent: G2/1.0 X-HTTP-UserAgent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; .NET CLR 2.0.50727; .NET CLR 3.0.04506.30),gzip(gfe),gzip(gfe) Complaints-To: groups-abuse@google.com Injection-Info: x35g2000prf.googlegroups.com; posting-host=62.220.8.122; posting-account=VhGBRA0AAAAPUct5VN1tGkfI2QuiqXqC To: pgsql-performance@postgresql.org X-Virus-Scanned: Maia Mailguard 1.0.1 X-Spam-Status: No, hits=0.001 tagged_above=0 required=5 tests=BAYES_50=0.001 X-Spam-Level: X-Archive-Number: 200705/426 X-Sequence-Number: 24816 I have rewritten the code like existing_words_array := ARRAY( select word from WORD_COUNTS where word = ANY ( array_of_words ) ); not_existing_words_array := ARRAY( select distinct_word from ( select distinct (array_of_words)[s.index] as distinct_word from generate_series(1, array_upper( array_of_words, 1 ) ) as s(index) ) as distinct_words where distinct_word <> ALL ( existing_words_array ) ); -- insert the missing words if not_existing_words_array is not null then insert into WORD_COUNTS ( word, count ) ( select word, 1 from ( select not_existing_words_array[s.index] as word from generate_series( 1, array_upper( not_existing_words_array, 1 ) ) as s(index) ) as distinct_words ); end if; -- update the counts if existing_words_array is not null then update WORD_COUNTS set count = COALESCE( count, 0 ) + 1 where sw_word = ANY ( existing_words_array ); end if; Now it processes a million records in 14 seconds... so it was probably the problem of looking up NOT IN WORD_COUNTS was way too expencive