Received: from localhost (unknown [200.46.204.183]) by mail.postgresql.org (Postfix) with ESMTP id C0EDE632B1A for ; Wed, 15 Apr 2009 17:26:04 -0300 (ADT) Received: from mail.postgresql.org ([200.46.204.86]) by localhost (mx1.hub.org [200.46.204.183]) (amavisd-maia, port 10024) with ESMTP id 28960-08 for ; Wed, 15 Apr 2009 17:25:59 -0300 (ADT) X-Greylist: domain auto-whitelisted by SQLgrey-1.7.6 Received: from mail-gx0-f172.google.com (mail-gx0-f172.google.com [209.85.217.172]) by mail.postgresql.org (Postfix) with ESMTP id C20C96322D5 for ; Wed, 15 Apr 2009 17:25:59 -0300 (ADT) Received: by gxk20 with SMTP id 20so258000gxk.19 for ; Wed, 15 Apr 2009 13:25:58 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=domainkey-signature:mime-version:received:in-reply-to:references :date:message-id:subject:from:to:content-type :content-transfer-encoding; bh=TeAFDCQMBU2krtFgqxWx4oT7burfiw8YqRlBFSQA/kU=; b=L0ObdeXW6a8qoK+giqaVt8NZsyUiHDZwb4Vbg3cOIkr541f0sSVJxi/BWlVvEUMszr lxVkMFj4v5i1RWuvQN+DXXSGXGssIlJ57TC/D3pPs0qyXNtomO80DM6orhgMgWkSC0Bp nZEgFv0PRKzblvsqxw7ANTqoWeRSmIc0oe8Vw= DomainKey-Signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma; h=mime-version:in-reply-to:references:date:message-id:subject:from:to :content-type:content-transfer-encoding; b=sLsSLfLEPPNrLB5LcPR2wJ1sDNSNHjKE5NUoznQq/KLkiD0nSEAtt8Z1RFf7aJMoGh tmqHKcCYq7vqQM0AKR23i7jktI33Lc+SUvm28WuH7eETp2jXsIRh6Ptz6xuH7PlZgCrU U0qBNf8Lh6tINpZPlnIz0Eqrqj/GgodVkx7KA= MIME-Version: 1.0 Received: by 10.151.10.7 with SMTP id n7mr884366ybi.187.1239827158733; Wed, 15 Apr 2009 13:25:58 -0700 (PDT) In-Reply-To: References: <49DC1034.1060705@frii.com> <49E36E1B.6020107@frii.com> Date: Wed, 15 Apr 2009 16:25:58 -0400 Message-ID: Subject: Re: changing multiple pk's in one update From: Glenn Maynard To: pgsql-sql@postgresql.org Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 7bit X-Virus-Scanned: Maia Mailguard 1.0.1 X-Spam-Status: No, hits=0 tagged_above=0 required=5 tests=none X-Spam-Level: X-Archive-Number: 200904/82 X-Sequence-Number: 32428 On Wed, Apr 15, 2009 at 8:43 AM, Jasen Betts wrote: > the update takes a long time too if it's updating all the rows. > and updating the index piecewise at the same time. > with the index extant I get from 20 (if the start and end ranges don't overlap) and 28s (with , > to 28 seconds (maximum overlap) for a table with 1000000 (short) rows He's using a compound key as his PK, eg. (entry, order), where there are only a few order values for each entry, so I think the real case is only updating order for a specific set of entries. >> I have continued searching for other ways to do this >> but most of my google results are floating in a sea >> of "update if insert fails, like mysql" results so >> I still have a little hope it is possible. >> I thought I remember seeing, a year or two ago, an >> update statement with an ordered subquery that avoided >> duplicate key errors but I am probably misrembering. Bear in mind that the update is failing based on the order the data is in the table, not the PK order. create table test (id integer primary key); insert into test (id) values (2), (1), (3); update test set id=id+1; ERROR: duplicate key value violates unique constraint "test_pkey" update test set id=id-1; ERROR: duplicate key value violates unique constraint "test_pkey" Both fail, because it tries to update 2 first. I suppose in a real pinch, you could renumber in two steps. For example, if you wanted to delete id 6 and move everything else down: insert into test (id) values (2), (7), (3), (1), (4), (5), (6), (8), (9); begin; set transaction isolation level serializable; delete from test where id=6; update test set id = id+1000000 where id >= 6; update test set id = id-1000001 where id >= 6; commit; Not very nice, but if "id" is really a sequence number starting at 1 in your case and not an always-increasing generated regular serial (so there's no chance of it actually reaching the arbitrarily large number 1000000), it should work. (It'd probably be workable for real serials, too, with a much larger offset.) If someone else creates a new sense for that entry after the first update, it'll sit on the order number you were about to use and the operation will fail. Serialize so nobody else will insert until you're done. -- Glenn Maynard