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 1tcn2m-002gje-IL for pgsql-performance@arkaria.postgresql.org; Tue, 28 Jan 2025 14:58:25 +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 1tcn2l-001c42-Js for pgsql-performance@arkaria.postgresql.org; Tue, 28 Jan 2025 14:58:23 +0000 Received: from makus.postgresql.org ([2001:4800:3e1:1::229]) by malur.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.94.2) (envelope-from ) id 1tcn2l-001c3V-7n for pgsql-performance@lists.postgresql.org; Tue, 28 Jan 2025 14:58:23 +0000 Received: from mail-yb1-xb2a.google.com ([2607:f8b0:4864:20::b2a]) by makus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (Exim 4.96) (envelope-from ) id 1tcn2j-001xSt-01 for pgsql-performance@postgresql.org; Tue, 28 Jan 2025 14:58:22 +0000 Received: by mail-yb1-xb2a.google.com with SMTP id 3f1490d57ef6-e587cca1e47so3521362276.0 for ; Tue, 28 Jan 2025 06:58:21 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1738076301; x=1738681101; darn=postgresql.org; h=to:subject:message-id:date:from:mime-version:from:to:cc:subject :date:message-id:reply-to; bh=CoSbB5WCGFCDSqmZu8uhMCFEEXarSccpGlFvFvv7840=; b=SEZnfTcFBcJ47rEGgQDcLwzWXywZHupyIc2r0ryg+e3vo4m6+fHAbiPIqsNqS7YAj4 b3riyjdmRlUxlfttwJVsniZKDPD0xQQnDLrCHPEvLviomOuYbjAREnBTJlGYAkXzRHY5 QkimgXn41QvTyuTgl57Rfjezd2ftIdGmx7RoITxLyFEQy7KXawuFoeP0ns9pL3kJbZFL iCj+mt05mAYrW4Z2BrEF4Nt+EF1SQtwUks9yMDrDhml6eQE/dcqYZ8JxUzWOkyb87vGs wXqPh1xwk0RSeYPGsa65VIHoRtZElcsckjXDMn0LseHEAekkfDxmjKuIFdAf70SPIlWT 6LvA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1738076301; x=1738681101; h=to:subject:message-id:date:from:mime-version:x-gm-message-state :from:to:cc:subject:date:message-id:reply-to; bh=CoSbB5WCGFCDSqmZu8uhMCFEEXarSccpGlFvFvv7840=; b=ByDlGFuYVmp84Td5xljsNVOyDX8qCQyIj5dgyh3oC8A361c66DsV+SFJ40xgRo4nuS OBwKFr0dZVeH7wsKBlaiwlDwwpHbaUKzapItzIdff99k90Xqh3oW0zyRUXH4reAKtx3j N7dYLEtBfYHxS0FOxLCvRH+5300EpEV9NZvLlcRQxvYweNlSh1mpiwTajcaFKxVM3ZRr x6F1MLcGEheA7rlucT+CbV3qVSUIf5c7BRAueBZgRFsMNZ8Vn1vcJxDfdP0oRfjBCp0i mjLPp/MLN8geNoKu9Kw1rPc6PFr5P+1lzHkJr1BpWFCyMMj6PlMttvmAXMzzUfZpOaj6 HiAQ== X-Gm-Message-State: AOJu0YwZTn+dTxqsycgpg1hIEep14o7W64x3u5NWSSR07Xh/Mri0duMJ hq/NOGpl1pwZEdh48Kq2LdwTgD3227CvuYh/hsQh+WGxEcB3aXhsgqhylyG7wzqxqEyvUf6D4Rp 0myF97ADJlTCl9bvrIBuT05Ey9hEHRfEE X-Gm-Gg: ASbGncs97+q7Khsfuvo6Usm0T819Kewf3JlpVl3yWJKg6r0p9LuwWQM87T0aw4bg1B4 +3HEWDz1uxT+Yly/1wmKqXn1khJrY1jCMpvxK1gw20UrgQDkskMXnMKZNjyonXVpYQVgNii/zrA == X-Google-Smtp-Source: AGHT+IF6HtywBTp0C4jeKSGO9yFYJhtGJrILHnOzf22zzOVokmqyoS072Nh2r0OxvXuV8q0EsgdDwL/Rm7/PJIpCDLg= X-Received: by 2002:a05:690c:3692:b0:6ef:6a91:4965 with SMTP id 00721157ae682-6f6eb93fadamr388783587b3.37.1738076300553; Tue, 28 Jan 2025 06:58:20 -0800 (PST) MIME-Version: 1.0 From: Clemens Eisserer Date: Tue, 28 Jan 2025 15:58:08 +0100 X-Gm-Features: AWEUYZnNXjKigKngJM2qYFc1OIFur6UxDCY19iYHEMCY0WsbSsSqcSSjRsQY0gg Message-ID: Subject: Why ORing with a false one-time filter turns an Index-Lookup into a SeqScan To: pgsql-performance@postgresql.org Content-Type: text/plain; charset="UTF-8" List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk Hello, Any idea what could cause postgresql (16.0) to fall back to a SeqScan when ORing a falsy one-time filter to a selection which would otherwise use an index scan? 1.) Without the false one-time condition, the query uses the existing index on owner to perform the lookup: select * from mytable where owner = current_setting('my.wfsuser', true); Bitmap Heap Scan on mytable (cost=43.92..12523.30 rows=3548 width=2341) (actual time=0.032..0.033 rows=0 loops=1) Recheck Cond: ((owner)::text = current_setting('my.wfsuser'::text, true)) -> Bitmap Index Scan on mytable_owner_idx (cost=0.00..43.04 rows=3548 width=0) (actual time=0.029..0.030 rows=0 loops=1) Index Cond: ((owner)::text = current_setting('my.wfsuser'::text, true)) Planning Time: 0.221 ms Execution Time: 0.094 ms 2.) also a static condition resulting in a false value is correctly recognized: select * from mytable where current_setting('my.wfsuser'::text, true) = 'admin'::text; Result (cost=0.01..158384.05 rows=709504 width=2341) (actual time=0.008..0.009 rows=0 loops=1) One-Time Filter: (current_setting('my.wfsuser'::text, true) = 'admin'::text) -> Seq Scan on mytable (cost=0.01..158384.05 rows=709504 width=2341) (never executed) Planning Time: 0.163 ms Execution Time: 0.068 ms 3.) Yet when both filters are combined with OR, postgresql executes a SeqScan: select * from mytable where owner = current_setting('my.wfsuser', true) OR current_setting('my.wfsuser'::text, true) = 'admin'::text; Gather (cost=1000.00..158909.23 rows=7077 width=2341) (actual time=2783.728..2786.520 rows=0 loops=1) Workers Planned: 2 Workers Launched: 2 -> Parallel Seq Scan on mytable (cost=0.00..157201.53 rows=2949 width=2341) (actual time=2744.147..2744.147 rows=0 loops=3) Filter: (((owner)::text = current_setting('my.wfsuser'::text, true)) OR (current_setting('my.wfsuser'::text, true) = 'admin'::text)) Rows Removed by Filter: 236501 Planning Time: 0.217 ms Execution Time: 2786.575 ms Thanks and best regards, Clemens