X-Original-To: pgsql-performance-postgresql.org@localhost.postgresql.org Received: from localhost (unknown [64.117.224.192]) by svr1.postgresql.org (Postfix) with ESMTP id D9DAFCBFBA; Mon, 14 Jul 2003 13:37:58 +0000 (GMT) Received: from svr1.postgresql.org ([64.117.224.193]) by localhost (svr4.postgresql.org [64.117.224.192]) (amavisd-new, port 10024) with ESMTP id 00191-04; Mon, 14 Jul 2003 13:38:15 +0000 (GMT) Received: from noao.edu (noao.edu [140.252.1.54]) by svr1.postgresql.org (Postfix) with ESMTP id 34128CBF6B; Mon, 14 Jul 2003 10:37:53 -0300 (ADT) Received: from weaver.tuc.noao.edu ([140.252.38.8] verified) by noao.edu (CommuniGate Pro SMTP 4.1b9) with ESMTP-TLS id 8070998; Mon, 14 Jul 2003 06:38:19 -0700 Received: from weaver.tuc.noao.edu (localhost.localdomain [127.0.0.1]) by weaver.tuc.noao.edu (8.12.8/8.12.5) with ESMTP id h6EDcIIY024693; Mon, 14 Jul 2003 06:38:18 -0700 Received: (from swampler@localhost) by weaver.tuc.noao.edu (8.12.8/8.12.8/Submit) id h6EDcIb3024691; Mon, 14 Jul 2003 06:38:18 -0700 X-Authentication-Warning: weaver.tuc.noao.edu: swampler set sender to swampler@noao.edu using -f Subject: Re: [SQL] Replacing a simple nested query? From: Steve Wampler Reply-To: swampler@noao.edu To: pgsql-sql@postgresql.org, Postgres-performance In-Reply-To: <20030713215042.GA18643@weaver.tuc.noao.edu> References: <20030713215042.GA18643@weaver.tuc.noao.edu> Content-Type: text/plain Content-Transfer-Encoding: 7bit Organization: National Solar Observatory Message-Id: <1058189898.23013.135.camel@weaver.tuc.noao.edu> Mime-Version: 1.0 X-Mailer: Ximian Evolution 1.4.0 Date: 14 Jul 2003 06:38:18 -0700 X-Virus-Scanned: by amavisd-new at postgresql.org X-Archive-Number: 200307/218 X-Sequence-Number: 2511 On Sun, 2003-07-13 at 14:50, Steve Wampler wrote: > I've got a simple nested query: > > select * from attributes where id in (select id from > attributes where (name='obsid') and (value='oid00066')); > > that performs abysmally. I've heard this described as the > 'classic WHERE IN' problem. > > Is there a better way to obtain the same results? The inner > select identifies a set of ids (2049 of them, to be exact) > that are then used to locate records that have the same id > (about 30-40K of those, including the aforementioned 2049). For the record, Joe Conway and Hannu Krosing both provided the same solution: select at.* from attributes_table at, attributes a where at.id = a.id and a.name='obsid' and a.value='oid00066'; which is several orders of infinity faster than than my naive approach above: ------------------------------------------------------------- lab.devel.configdb=# explain analyze select * from attributes_table where id in (select id from attributes where (name='obsid') and (value='oid00066')) order by id; NOTICE: QUERY PLAN: Index Scan using id_index on attributes_table (cost=0.00..8773703316.10 rows=241201 width=59) (actual time=136297.91..3418016.04 rows=32799 loops=1) SubPlan -> Materialize (cost=18187.48..18187.48 rows=15 width=25) (actual time=0.01..1.68 rows=1979 loops=482402) -> Index Scan using name_index on attributes_table (cost=0.00..18187.48 rows=15 width=25) (actual time=0.27..251.95 rows=2049 loops=1) Total runtime: 3418035.38 msec -------------------------------------------------------------- lab.devel.configdb=# explain analyze select at.* from attributes_table at, attributes a where at.id = a.id and a.name='obsid' and a.value='oid00066'; NOTICE: QUERY PLAN: Nested Loop (cost=0.00..18739.44 rows=217 width=84) (actual time=0.76..1220.65 rows=32799 loops=1) -> Index Scan using name_index on attributes_table (cost=0.00..18187.48 rows=15 width=25) (actual time=0.47..507.31 rows=2049 loops=1) -> Index Scan using id_index on attributes_table at (cost=0.00..35.80 rows=12 width=59) (actual time=0.11..0.31 rows=16 loops=2049) Total runtime: 1235.42 msec ------------------------------------------------------------------- My thanks to both Joe and Hannu! Steve -- Steve Wampler -- swampler@noao.edu Quantum materiae materietur marmota monax si marmota monax materiam possit materiari?