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 4263E528D5 for ; Wed, 29 Jun 2005 03:37:05 -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 67718-03 for ; Wed, 29 Jun 2005 06:36:55 +0000 (GMT) Received: from zproxy.gmail.com (zproxy.gmail.com [64.233.162.196]) by svr1.postgresql.org (Postfix) with ESMTP id 1D08C52820 for ; Wed, 29 Jun 2005 03:36:53 -0300 (ADT) Received: by zproxy.gmail.com with SMTP id s18so87141nze for ; Tue, 28 Jun 2005 23:36:52 -0700 (PDT) DomainKey-Signature: a=rsa-sha1; q=dns; c=nofws; s=beta; d=gmail.com; h=received:message-id:date:from:reply-to:to:subject:cc:in-reply-to:mime-version:content-type:content-transfer-encoding:content-disposition:references; b=pzcPfeR2M1/vKtJiHm2s6JtFN3be+xWpoq4TiX19VvJ/CWJ+91bL35ECwlkAa6o5z7Eqi0nPkrZsP1S5yYiCsaN437rm7OJ4uDo5FokAXkbzNmqbSC6Mx9xMkwHw+fS9jwwE5r5rktJodprSmcBn85CHP0LwZz5mxo6vVNtIf3s= Received: by 10.36.222.40 with SMTP id u40mr6353982nzg; Tue, 28 Jun 2005 23:36:52 -0700 (PDT) Received: by 10.36.22.20 with HTTP; Tue, 28 Jun 2005 23:36:52 -0700 (PDT) Message-ID: <758d5e7f05062823361c8840f4@mail.gmail.com> Date: Wed, 29 Jun 2005 08:36:52 +0200 From: Dawid Kuroczko Reply-To: Dawid Kuroczko To: John A Meinel Subject: Re: tricky query Cc: Merlin Moncure , Bruno Wolff III , Postgresql Performance , elein In-Reply-To: <42C1A81D.1060507@arbash-meinel.com> Mime-Version: 1.0 Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: quoted-printable Content-Disposition: inline References: <6EE64EF3AB31D5448D0007DD34EEB3415C2C07@Herge.rcsinc.local> <42C1A81D.1060507@arbash-meinel.com> X-Virus-Scanned: by amavisd-new at hub.org X-Spam-Status: No, hits=0.629 tagged_above=0 required=5 tests=AWL, FROM_ENDS_IN_NUMS, RCVD_BY_IP X-Spam-Level: X-Archive-Number: 200506/584 X-Sequence-Number: 13221 On 6/28/05, John A Meinel wrote: > Actually, if you already have a lower bound, then you can change it to: >=20 > SELECT t1.id+1 as id_new FROM id_test t1 > WHERE t1.id > id_min > AND NOT EXISTS > (SELECT t2.id FROM id_test t2 WHERE t2.id =3D t1.id+1) > ORDER BY t1.id LIMIT 1; >=20 > This would actually really help performance if you have a large table > and then empty entries start late. You can also boost performance by creating a functional index! CREATE UNIQUE INDEX id_test_id1_index ON id_test ((id+1)); ...and then joining two tables and filtering results. PostgreSQL (8.x) will do Merge Full Join which will use both the indexes: SELECT t2.id+1 FROM id_test t1 FULL OUTER JOIN id_test t2 ON (t1.id =3D t2.id+1) WHERE t1.id IS NULL LIMIT 1; Limit (cost=3D0.00..1.52 rows=3D1 width=3D4) -> Merge Full Join (cost=3D0.00..1523122.73 rows=3D999974 width=3D4) Merge Cond: ("outer".id =3D ("inner".id + 1)) Filter: ("outer".id IS NULL) -> Index Scan using id_test_pkey on id_test t1=20 (cost=3D0.00..18455.71 rows=3D999974 width=3D4) -> Index Scan using id_test_id1_index on id_test t2=20 (cost=3D0.00..1482167.60 rows=3D999974 width=3D4) (6 rows) ...the only drawback is having to keep two indexes instead of just one. But for large tables I think it is really worth it For my test case, the times are (1-1000000 range with 26 missing rows): NOT EXISTS -- 670ms NOT IN -- 1800ms indexed FULL OUTER -- 267ms Regards, Dawid PS: Does it qualify for General Bits? ;-)))