Received: from malur.postgresql.org ([217.196.149.56]) by arkaria.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.94.2) (envelope-from ) id 1rZpdV-006e65-I8 for pgsql-hackers@arkaria.postgresql.org; Tue, 13 Feb 2024 10:03:34 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.94.2) (envelope-from ) id 1rZpdU-00GjJL-NZ for pgsql-hackers@arkaria.postgresql.org; Tue, 13 Feb 2024 10:03:32 +0000 Received: from magus.postgresql.org ([2a02:c0:301:0:ffff::29]) by malur.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.94.2) (envelope-from ) id 1rZpdU-00Gj6u-68 for pgsql-hackers@lists.postgresql.org; Tue, 13 Feb 2024 10:03:32 +0000 Received: from mail.postgrespro.ru ([93.174.131.139]) by magus.postgresql.org with esmtps (TLS1.2) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.94.2) (envelope-from ) id 1rZpdP-006xgr-64 for pgsql-hackers@postgresql.org; Tue, 13 Feb 2024 10:03:31 +0000 Received: from [172.30.0.166] (unknown [172.30.0.166]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (Client did not present a certificate) (Authenticated sender: a.lepikhov@postgrespro.ru) by mail.postgrespro.ru (Postfix/587) with ESMTPSA id DAB3DE20E31; Tue, 13 Feb 2024 13:03:22 +0300 (MSK) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=postgrespro.ru; s=mx2023; t=1707818605; bh=Em1eEj/87o5DLu/jczVDi8K0xntmYW0sn9AiGwKzbYE=; h=Message-ID:Date:User-Agent:Subject:To:Cc:References:From: In-Reply-To:From; b=fP86FVDZB/eDhlYBlaTwf3lHXcE1Pv2ab7A9OJe0BqDnA08t0x3IGrNL3D0C9vjMH N7vKN9Lq5WiLPrGSp3hovHGNyxZM5lgJijlMZd0ZMY1u5MldniHWVfmppjT41cJ3Jo V+xn5YMgh6PckBCobYkj0OBFE8xZ/1Ru9csQemphrHDfm8ZJPOUCVisvy+T8inf176 GosCzKy0KmHprAeEdB4t4Ho2ef7sm3e0Y3TeAqY+UPQ3c7juyj7m/ujh+7x5cirHvU sLbjuQHgiNSBmElkqm2AUll3uDaFNE7gx0m0mmsy6TK3mNbsqFzzzCPPjxPI1aKUGE 7cgy9EM6c9wZQ== Message-ID: Date: Tue, 13 Feb 2024 17:03:20 +0700 MIME-Version: 1.0 User-Agent: Mozilla Thunderbird Subject: Re: POC, WIP: OR-clause support for indexes Content-Language: en-US To: jian he Cc: Alena Rybakina , Alexander Korotkov , Robert Haas , pgsql-hackers@postgresql.org, Peter Geoghegan , "Finnerty, Jim" , Marcos Pegoraro , teodor@sigaev.ru, Ranier Vilela , Tomas Vondra , Peter Eisentraut References: <567ED6CA.2040504@sigaev.ru> <04ef16eb-46c1-4ce7-9f68-d1c80ef0be81@postgrespro.ru> <59e67a40-95a8-4d74-ae4e-027ea0f59084@postgrespro.ru> <59b77a8a-29d6-4727-bf26-4a30a6a9719a@postgrespro.ru> <32d23d97-d07f-4d44-9933-ba3295fb3ed8@postgrespro.ru> <7e11e27b-7ab9-4d59-af0a-a921861a9206@postgrespro.ru> <13ad923a-33df-4b44-9e00-c9323cd4c37d@postgrespro.ru> From: Andrei Lepikhov Organization: Postgres Professional In-Reply-To: Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 7bit List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk On 13/2/2024 07:00, jian he wrote: > + newa = makeNode(ArrayExpr); > + /* array_collid will be set by parse_collate.c */ > + newa->element_typeid = scalar_type; > + newa->array_typeid = array_type; > + newa->multidims = false; > + newa->elements = aexprs; > + newa->location = -1; > > I am confused by the comments `array_collid will be set by > parse_collate.c`, can you further explain it? I wonder if the second paragraph of comments on commit b310b6e will be enough to dive into details. > if OR expression right arm is not plain Const, but with collation > specification, eg. > `where a = 'a' collate "C" or a = 'b' collate "C";` > > then the rightop is not Const, it will be CollateExpr, it will not be > used in transformation. Yes, it is done for simplicity right now. I'm not sure about corner cases of merging such expressions. > > set enable_or_transformation to on; > explain(timing off, analyze, costs off) > select count(*) from test where (x = 1 or x = 2 or x = 3 or x = 4 or x > = 5 or x = 6 or x = 7 or x = 8 or x = 9 ) \watch i=0.1 c=10 > 35.376 ms > > The time is the last result of the 10 iterations. The reason here - parallel workers. If you see into the plan you will find parallel workers without optimization and absence of them in the case of optimization: Gather (cost=1000.00..28685.37 rows=87037 width=12) (actual rows=90363 loops=1) Workers Planned: 2 Workers Launched: 2 -> Parallel Seq Scan on test Filter: ((x = 1) OR (x = 2) OR (x = 3) OR (x = 4) OR (x = 5) OR (x = 6) OR (x = 7) OR (x = 8) OR (x = 9)) Seq Scan on test (cost=0.02..20440.02 rows=90600 width=12) (actual rows=90363 loops=1) Filter: (x = ANY ('{1,2,3,4,5,6,7,8,9}'::integer[])) Having 90600 tuples returned we estimate it into 87000 (less precisely) without transformation and 90363 (more precisely) with the transformation. But if you play with parallel_tuple_cost and parallel_setup_cost, you will end up having these parallel workers: Gather (cost=0.12..11691.03 rows=90600 width=12) (actual rows=90363 loops=1) Workers Planned: 2 Workers Launched: 2 -> Parallel Seq Scan on test Filter: (x = ANY ('{1,2,3,4,5,6,7,8,9}'::integer[])) Rows Removed by Filter: 303212 And some profit about 25%, on my laptop. I'm not sure about the origins of such behavior, but it seems to be an issue of parallel workers, not this specific optimization. -- regards, Andrei Lepikhov Postgres Professional