Received: from malur.postgresql.org ([217.196.149.56]) by arkaria.postgresql.org with esmtp (Exim 4.80) (envelope-from ) id 1YTbvl-00040l-RZ for pgsql-sql@arkaria.postgresql.org; Thu, 05 Mar 2015 19:59:38 +0000 Received: from localhost ([127.0.0.1] helo=postgresql.org) by malur.postgresql.org with smtp (Exim 4.80) (envelope-from ) id 1YTbvk-0004Qa-C1 for pgsql-sql@arkaria.postgresql.org; Thu, 05 Mar 2015 19:59:36 +0000 Received: from makus.postgresql.org ([2001:4800:1501:1::229]) by malur.postgresql.org with esmtps (TLS1.2:DHE_RSA_AES_256_CBC_SHA256:256) (Exim 4.80) (envelope-from ) id 1YTbvj-0004QR-4e for pgsql-sql@postgresql.org; Thu, 05 Mar 2015 19:59:35 +0000 Received: from out2-smtp.messagingengine.com ([66.111.4.26]) by makus.postgresql.org with esmtps (TLS1.2:DHE_RSA_AES_256_CBC_SHA256:256) (Exim 4.80) (envelope-from ) id 1YTbve-0004lc-Vl for pgsql-sql@postgresql.org; Thu, 05 Mar 2015 19:59:32 +0000 Received: from compute5.internal (compute5.nyi.internal [10.202.2.45]) by mailout.nyi.internal (Postfix) with ESMTP id CC1FC20BE3 for ; Thu, 5 Mar 2015 14:59:28 -0500 (EST) Received: from frontend2 ([10.202.2.161]) by compute5.internal (MEProxy); Thu, 05 Mar 2015 14:59:30 -0500 DKIM-Signature: v=1; a=rsa-sha1; c=relaxed/relaxed; d=aklaver.com; h= x-sasl-enc:message-id:date:from:mime-version:to:subject :references:in-reply-to:content-type:content-transfer-encoding; s=mesmtp; bh=ldrhK8ZwBzb5O6u/kpueVJM3Jhs=; b=P9EKoHKulXKbF4pSAM EP1IHTYRNLgdthH6zq6qGu9jnpwuVVpF0RaRNNuTxk/z2Fl7TgUDZvxGz3yjQ+qw 5ViLRhDykytaiuttMh00/7l02adUqvN1b9vWDvSXGDuMmI+WMmlGYAizWx27eSpx sgofTuiZViGUfKSc3jG9V/Ay4= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed/relaxed; d= messagingengine.com; h=x-sasl-enc:message-id:date:from :mime-version:to:subject:references:in-reply-to:content-type :content-transfer-encoding; s=smtpout; bh=ldrhK8ZwBzb5O6u/kpueVJ M3Jhs=; b=UcHdDXOf1xXCqpm5Mnb2cv/VQs/DJjzdQ1rt6/ld4SxNsc2xxidu5z JYvWvzu8ahd6BmEXbIAYTjlpqPxVttcfsY75uekvRxsVIt7MbhuxOErqpqmLRl33 NqDQgV96dmHmcAWtcVeDOzgb0AgrYdJfB0rTTfb6LylS001Epq460= X-Sasl-enc: zHUFgXMgFEd1M4jz6dVRuXuUReL7B/BrPKETIXBCVs6z 1425585569 Received: from killi.site (unknown [50.197.80.2]) by mail.messagingengine.com (Postfix) with ESMTPA id 95E8668021D; Thu, 5 Mar 2015 14:59:29 -0500 (EST) Message-ID: <54F8B5A0.4020607@aklaver.com> Date: Thu, 05 Mar 2015 11:59:28 -0800 From: Adrian Klaver User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:31.0) Gecko/20100101 Thunderbird/31.5.0 MIME-Version: 1.0 To: Andreas Joseph Krogh , "pgsql-sql@postgresql.org" Subject: Re: Schema for caching message-count in folders using triggers References: In-Reply-To: Content-Type: text/plain; charset=utf-8; format=flowed Content-Transfer-Encoding: 7bit X-Pg-Spam-Score: -2.7 (--) List-Archive: List-Help: List-ID: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: X-Mailing-List: pgsql-sql Precedence: bulk Sender: pgsql-sql-owner@postgresql.org On 03/05/2015 11:45 AM, Andreas Joseph Krogh wrote: > Hi all. > I'm facing a problem with my current schema for email where folders > start containing several 100K of messages and count(*) in them taks > noticeable time. This schema is accessible from IMAP and a web-app so > lots of queries of the type "list folders with message count" are performed. > So, I'm toying with this idea of caching the message-count in the > folder-table itself. > I currently have this: > > CREATE or replace FUNCTIONcount_increment_tf()RETURNS TRIGGER AS$_$ > BEGIN > UPDATE folder SETmessage_count =message_count + 1 WHEREid =NEW.folder_id; > RETURNNEW; > END $_$LANGUAGE'plpgsql'; > > CREATE or replace FUNCTIONcount_decrement_tf()RETURNS TRIGGER AS$_$ > BEGIN > UPDATE folder SETmessage_count =message_count - 1 WHEREid =OLD.folder_id; > RETURNOLD; > END $_$LANGUAGE'plpgsql'; > > CREATE or replace FUNCTIONcount_update_tf()RETURNS TRIGGER AS$_$ > BEGIN > UPDATE folder SETmessage_count =message_count - 1 WHEREid =OLD.folder_id; > UPDATE folder SETmessage_count =message_count + 1 WHEREid =NEW.folder_id; > RETURNNEW; > END $_$LANGUAGE'plpgsql'; > > CREATE TRIGGERincrement_folder_msg_tAFTER INSERT ON message FOR EACH ROW EXECUTE PROCEDUREcount_increment_tf(); > CREATE TRIGGERdecrement_folder_msg_tAFTER DELETE ON message FOR EACH ROW EXECUTE PROCEDUREcount_decrement_tf(); > CREATE TRIGGERupdate_folder_msg_tAFTER UPDATE ON message FOR EACH ROW EXECUTE PROCEDUREcount_update_tf(); > > The problem with this is locking (waiting for another TX to commit when > updating the same folder) and deadlock issues when trying to > simultaneously insert/delete/update messages in a folder. > Does anyone have any better ideas for safely caching the message-count > in each folder without locking and deadlock issues? How accurate does this have to be? Not exactly following what is folder? Is it a table that contains the messages? A top of the head idea would be to use sequences. Create a sequence for each folder starting at current count and then use nextval, setval to change the value: http://www.postgresql.org/docs/9.4/interactive/functions-sequence.html It is not transactional, so it would probably not be spot on, which is why I asked about accuracy earlier. > Thanks. > -- > *Andreas Joseph Krogh* > CTO / Partner - Visena AS > Mobile: +47 909 56 963 > andreas@visena.com > www.visena.com > -- Adrian Klaver adrian.klaver@aklaver.com -- Sent via pgsql-sql mailing list (pgsql-sql@postgresql.org) To make changes to your subscription: http://www.postgresql.org/mailpref/pgsql-sql