Received: from makus.postgresql.org (makus.postgresql.org [98.129.198.125]) by mail.postgresql.org (Postfix) with ESMTP id 640C9862DB2 for ; Wed, 8 Feb 2012 14:03:43 -0400 (AST) Received: from ch1ehsobe002.messaging.microsoft.com ([216.32.181.182] helo=ch1outboundpool.messaging.microsoft.com) by makus.postgresql.org with esmtp (Exim 4.72) (envelope-from ) id 1RvBro-0005iT-P3 for pgsql-performance@postgresql.org; Wed, 08 Feb 2012 18:03:43 +0000 Received: from mail182-ch1-R.bigfish.com (10.43.68.225) by CH1EHSOBE009.bigfish.com (10.43.70.59) with Microsoft SMTP Server id 14.1.225.23; Wed, 8 Feb 2012 18:03:27 +0000 Received: from mail182-ch1 (localhost [127.0.0.1]) by mail182-ch1-R.bigfish.com (Postfix) with ESMTP id E91F7180418; Wed, 8 Feb 2012 18:03:26 +0000 (UTC) X-SpamScore: -14 X-BigFish: VS-14(zz15bfK1e83M1443Nzz1202hzzz2fh87h2a8h668h839h946h) X-Forefront-Antispam-Report: CIP:131.107.125.8; KIP:(null); UIP:(null); IPV:NLI; H:TK5EX14HUBC107.redmond.corp.microsoft.com; RD:none; EFVD:NLI Received-SPF: pass (mail182-ch1: domain of skype.net designates 131.107.125.8 as permitted sender) client-ip=131.107.125.8; envelope-from=david.yeu@skype.net; helo=TK5EX14HUBC107.redmond.corp.microsoft.com ; icrosoft.com ; X-FB-DOMAIN-IP-MATCH: fail Received: from mail182-ch1 (localhost.localdomain [127.0.0.1]) by mail182-ch1 (MessageSwitch) id 1328724205112517_9414; Wed, 8 Feb 2012 18:03:25 +0000 (UTC) Received: from CH1EHSMHS004.bigfish.com (snatpool2.int.messaging.microsoft.com [10.43.68.232]) by mail182-ch1.bigfish.com (Postfix) with ESMTP id 0DD2C4004B; Wed, 8 Feb 2012 18:03:25 +0000 (UTC) Received: from TK5EX14HUBC107.redmond.corp.microsoft.com (131.107.125.8) by CH1EHSMHS004.bigfish.com (10.43.70.4) with Microsoft SMTP Server (TLS) id 14.1.225.23; Wed, 8 Feb 2012 18:03:24 +0000 Received: from TK5EX14MBXC124.redmond.corp.microsoft.com ([169.254.4.55]) by TK5EX14HUBC107.redmond.corp.microsoft.com ([157.54.80.67]) with mapi id 14.02.0247.005; Wed, 8 Feb 2012 10:03:05 -0800 From: David Yeu To: "pgsql-performance@postgresql.org" CC: "ops@groupme.com" Subject: Performance on large, append-only tables Thread-Topic: Performance on large, append-only tables Thread-Index: AQHM5ovnYCO7suNXYU6tt8KY8JsaNg== Date: Wed, 8 Feb 2012 18:03:04 +0000 Message-ID: Accept-Language: en-US Content-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: x-originating-ip: [157.54.51.34] Content-Type: text/plain; charset="Windows-1252" Content-ID: Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 X-OriginatorOrg: microsoft.com X-Pg-Spam-Score: -2.6 (--) X-Archive-Number: 201202/84 X-Sequence-Number: 46256 Hi there, We've got a pretty large table that sees millions of new rows a day, and we're trying our best to optimize queries against it. We're hoping to find some guidance on this list. Thankfully, the types of queries that we perform against this table are pretty constrained. We never update rows and we never join against other tables. The table essentially looks like this: | id | group_id | created_at | everything else=8A Where `id' is the primary key, auto-incrementing, `group_id' is the foreign key that we always scope against, and `created_at' is the insertion time. We have indices against the primary key and the group_id. Our queries essentially fall into the following cases: * =8A WHERE group_id =3D ? ORDER BY created_at DESC LIMIT 20; * =8A WHERE group_id =3D ? AND id > ? ORDER BY created_at DESC; * =8A WHERE group_id =3D ? AND id < ? ORDER BY created_at DESC LIMIT 20; * =8A WHERE group_id =3D ? ORDER BY created_at DESC LIMIT 20 OFFSET ?; In human words, we're looking for: * The most recent (20) rows. * The most recent rows after a given `id'. * Twenty rows before a given `id'. * Pages of twenty rows. Originally, this table was part of our primary database, but recently we saw queries take upwards of thirty seconds or more to complete. Since we're serving web requests, that's basically unacceptable, and caused a lot of requests to backup. Our interim solution has been to simply carve out a new database that hosts only this table, and that has worked to some degree. We aren't seeing thirty seconds plus database response times anymore, but some queries still take many seconds and the cost of spinning up a new master-slave configuration hasn't been cheap. In the meantime, we're hoping to investigate other ways to optimize this table and the queries against it. Heroku's data team has suggested balling up these rows into arrays, where a single row would represent a group_id, and the data would occupy a single column as an array. We don't have any experience with this and were wondering if anyone here has tried it. And finally, we're also trying out alternative stores, since it seems like this data and its retrieval could be well suited to document-oriented backends. Redis and DynamoDB are currently the best contenders. Thanks in advance for any help, Regards, Dave Yeu & Neil Sarkar GroupMe