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 1E3935299C for ; Thu, 11 Aug 2005 09:08:37 -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 36300-02 for ; Thu, 11 Aug 2005 12:08:34 +0000 (GMT) Received: from boutiquenumerique.com (boutiquenumerique.com [82.67.9.10]) by svr1.postgresql.org (Postfix) with ESMTP id 04E1052983 for ; Thu, 11 Aug 2005 09:08:32 -0300 (ADT) Received: (qmail 18274 invoked from network); 11 Aug 2005 14:08:50 +0200 Received: from unknown (HELO localhost) (boutiquenumerique-lists@192.168.0.4) by boutiquenumerique.com with SMTP; 11 Aug 2005 14:08:50 +0200 To: "Tino Wildenhain" , "Gavin Sherry" Cc: "Mark Cotner" , "Dan Harris" , pgsql-performance@postgresql.org Subject: Re: Speedier count(*) References: <1123745049.27613.1.camel@Andrea.peacock.de> <1123757536.27613.10.camel@Andrea.peacock.de> Message-ID: Date: Thu, 11 Aug 2005 14:08:34 +0200 From: PFC Organization: =?iso-8859-15?Q?La_Boutique_Num=E9rique?= Content-Type: text/plain; format=flowed; delsp=yes; charset=iso-8859-15 MIME-Version: 1.0 Content-Transfer-Encoding: 8bit In-Reply-To: <1123757536.27613.10.camel@Andrea.peacock.de> User-Agent: Opera M2/8.0 (Linux, build 1095) X-Virus-Scanned: by amavisd-new at hub.org X-Spam-Status: No, hits=0.005 tagged_above=0 required=5 tests=[AWL=0.005] X-Spam-Level: X-Archive-Number: 200508/115 X-Sequence-Number: 13862 > You could lock the count table to prevent the problem > where 2 competing transactions do an insert, read the > start value and add 1 to it and then write the result > - which is n+1 rather then n+2 - so you are off by one. > Think of the same when one transaction inserts 100 > and the other 120. Then you could even be off by 100. Niet. If your trigger does UPDATE counts_cache SET cached_count = cached_count+N WHERE ... Then all locking is taken care of by Postgres. Of course if you use 2 queries then you have locking issues. However the UPDATE counts_cache has a problem, ie. it locks this row FOR UPDATE for the whole transaction, and all transactions which want to update the same row must wait to see if the update commits or rollbacks, so if you have one count cache row for the whole table you get MySQL style scalability... To preserve scalability you could, instead of UPDATE, INSERT the delta of rows inserted/deleted in a table (which has no concurrencies issues) and compute the current count with the sum() of the deltas, then with a cron, consolidate the deltas and update the count_cache table so that the deltas table stays very small.