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.96) (envelope-from ) id 1w2jRN-000Y2Z-0U for pgsql-performance@arkaria.postgresql.org; Wed, 18 Mar 2026 05:27:33 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.96) (envelope-from ) id 1w2jRM-007bqz-0B for pgsql-performance@arkaria.postgresql.org; Wed, 18 Mar 2026 05:27: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.96) (envelope-from ) id 1w2jRL-007bqO-2L for pgsql-performance@lists.postgresql.org; Wed, 18 Mar 2026 05:27:31 +0000 Received: from mail-lf1-x12e.google.com ([2a00:1450:4864:20::12e]) by magus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (Exim 4.98.2) (envelope-from ) id 1w2jRJ-00000000sNw-1Urf for pgsql-performance@lists.postgresql.org; Wed, 18 Mar 2026 05:27:31 +0000 Received: by mail-lf1-x12e.google.com with SMTP id 2adb3069b0e04-5a13a06fc85so7444984e87.1 for ; Tue, 17 Mar 2026 22:27:29 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1773811649; x=1774416449; darn=lists.postgresql.org; h=in-reply-to:from:content-language:references:cc:to:subject :user-agent:mime-version:date:message-id:from:to:cc:subject:date :message-id:reply-to; bh=40ZsS2Uru0ksoalsVglXmbGFUbKi5UYOYAtJhjZZJac=; b=RgF4ug7Vv/BsR5o/Y89hndVr2SMdfid/zNKXaIHxk/GsyLLwlZhB6D5BXEnhuur95+ CydS5F8a8d3lhoeyu2Gv/4olsD9Spfob7WIJeJQJU60UZrWFelB0+qjEeasoIfAV9oz9 6FSDGwwgMG8EWCgmXFMzid0HMLmjiQ3eGEBLXT7q7q2/1BD8K5TtN4x5bttfiDL24bwg eJkjs8O32/tONC7E7c5D4z9bHxYMvknxp8UqIWdFT92LfGjoRK1oaviSzhVLKiIdJYJc QtEX/gg4BpFjnUDwZ52+n6lXL+ThTy2Kbt9Wn4LlTDXsrNXjG176L9zdWuxYOPuQIimR 8SXQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1773811649; x=1774416449; h=in-reply-to:from:content-language:references:cc:to:subject :user-agent:mime-version:date:message-id:x-gm-gg:x-gm-message-state :from:to:cc:subject:date:message-id:reply-to; bh=40ZsS2Uru0ksoalsVglXmbGFUbKi5UYOYAtJhjZZJac=; b=OnGX2Fm0hB7ELNsEh4/HYFXoL2szHJHwWpvfZzuAHkPTnr0oXsw9xp5pSTCxnFnoz8 rd/VtM9xxXrJSF0sWq2O962RuXE5tHVJofC/iuPo9h4Uyo5JAtcNJxjYmrl2UzmmMGKX H5nqQhf9Iis+WLJAkY546zN1fkBW3wKCO362gsoiWi9gkO91pvZS//MQXS03iRc8Ft/B GKwNJlCvPAGdtQwVkZz8AO3E/FdaFtMK+AsRux8F5ygmjvwi77xEEY8rlSMCHv2B8kas M87VnDSBbUbl5j5JglLVhUlyMrXB6ZNWV9TkOB2iGJLnJTW5uPnyD3e3WVCG3M08Gqwm KD1w== X-Gm-Message-State: AOJu0Yz8nd6LUENufHCkQQVLyoRgIuKSDG9Brhm4SQG9Zf1LJVw9ezCD 1z8IyylEBt9NerR3OL/3fJkN+86zSfI8XH9ZX0srIrGzu3jmUoRJj3Jp X-Gm-Gg: ATEYQzwqJBhYo5CTVpuioK74g1AssB7WpdyqwOIiBIcnECYQE288u/AKBpDI4s6IQkG b5HVVgWLh91cEqIohCWED9XAJQTO7IXDTGPNArin9TBOjfAob/cmnCiN136vVBOzsipApjaa7WV pLfB4SCG6fiZYC7C8miUtDA3NisthgqMM2i+j7DiRiIX6b06MQHPgbSGA5cnpu3NE28N0O6LiLE RTLhPQaHMXybZvAaZ4GTrvK/yURbS36hcPf+QZC7MESjQlTbNFQlCltDfGqCwb9hiXGTI1n2XxG 2eI3miTb6tnJ5BgrfTzpbnN5KIIxCCkYnnX4F2eYcSeOaJgen/JqVz1AdAmJJ6sAsGDnfGxEI4G NXPMlJsYY6U/M99AkcZQFltD2mKmZHyV5znfczDAL+0dZ74fZ9OOmSjIxmdEElVCAAHadWPKNWA 4iy+MfEeD1Wr3P23jj8TFhWj1EXaiCsw== X-Received: by 2002:a19:f61a:0:b0:5a1:1862:67a0 with SMTP id 2adb3069b0e04-5a2796bb07dmr568744e87.45.1773811648806; Tue, 17 Mar 2026 22:27:28 -0700 (PDT) Received: from [192.168.1.233] ([94.137.43.152]) by smtp.gmail.com with ESMTPSA id 2adb3069b0e04-5a279c27351sm311916e87.15.2026.03.17.22.27.27 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Tue, 17 Mar 2026 22:27:28 -0700 (PDT) Content-Type: multipart/alternative; boundary="------------d7KfeKs6elDgvnOG12QYy4lP" Message-ID: <381e7d47-8021-458d-9a64-0cdb80b004f0@gmail.com> Date: Wed, 18 Mar 2026 11:27:26 +0600 MIME-Version: 1.0 User-Agent: Mozilla Thunderbird Subject: Re: postgres chooses objectively wrong index To: Merlin Moncure , Tom Lane Cc: pgsql-performance@lists.postgresql.org References: <574349.1773786268@sss.pgh.pa.us> Content-Language: en-US From: Alexey Ermakov In-Reply-To: List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk This is a multi-part message in MIME format. --------------d7KfeKs6elDgvnOG12QYy4lP Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 8bit On 2026-03-18 04:52, Merlin Moncure wrote: > On Tue, Mar 17, 2026 at 4:16 PM Alexey Ermakov > wrote: > > On 2026-03-18 03:01, Merlin Moncure wrote: >> I've been maintaining an airflow style orchestrator in pl/pgsql, >> and it's revealed a performance issue I just can't solve.  There >> is a table, task, which may normally contain billions of rows, >> but only a tiny portion is interesting for specific reasons—a >> common pattern in task-type systems. >> >> ... >> >> I'm wondering if there are other tricks that might apply here, >> for example, multi column index statistics...curious if anyone >> has thoughts on that. >> >> Any suggestions? >> >> merlin >> > Hello. I think planner doesn't have information about distribution > of *async.task_execution_state(task)* unless it's part of any full > index. I would try to give that with extended statistics > (postgresql 14+): > > create statistics (mcv) task_task_execution_state_stat on ((async.task_execution_state(task))) from async.task; > analyze async.task; > > If that won't help - please show distribution from pg_stats_ext > view for extended statistic above. > > > This unfortunately fails, probably because the table type includes > system columns (despite not using them). > orchestrator_service_user@orchestrator=> create statistics  task_stats > (mcv) on (async.task_execution_state(task)) from async.task; > ERROR:  statistics creation on system columns is not supported > > This would require some refactoring to fix. Interesting... In that case functional index should help (as it also makes statistic for the planner): create index concurrently on task_task_execution_state_idx async.task using btree ((async.task_execution_state(task))); analyze async.task; Perhaps multicolumn index will also help for queries but hard to say without knowing distributions. We could check state distribution info after index creation and analyze with query like this: select * from pg_stats where tablename = 'task_task_execution_state_idx' \gx -- Alexey Ermakov --------------d7KfeKs6elDgvnOG12QYy4lP Content-Type: text/html; charset=UTF-8 Content-Transfer-Encoding: 8bit
On 2026-03-18 04:52, Merlin Moncure wrote:
On Tue, Mar 17, 2026 at 4:16 PM Alexey Ermakov <alexius.work@gmail.com> wrote:
On 2026-03-18 03:01, Merlin Moncure wrote:
I've been maintaining an airflow style orchestrator in pl/pgsql, and it's revealed a performance issue I just can't solve.  There is a table, task, which may normally contain billions of rows, but only a tiny portion is interesting for specific reasons—a common pattern in task-type systems.

...

I'm wondering if there are other tricks that might apply here, for example, multi column index statistics...curious if anyone has thoughts on that.

Any suggestions?

merlin

Hello. I think planner doesn't have information about distribution of async.task_execution_state(task) unless it's part of any full index. I would try to give that with extended statistics (postgresql 14+):

create statistics (mcv) task_task_execution_state_stat on ((async.task_execution_state(task))) from async.task;
analyze async.task;

If that won't help - please show distribution from pg_stats_ext view for extended statistic above.


This unfortunately fails, probably because the table type includes system columns (despite not using them).
 
orchestrator_service_user@orchestrator=> create statistics  task_stats (mcv) on (async.task_execution_state(task)) from async.task;
ERROR:  statistics creation on system columns is not supported

This would require some refactoring to fix.

Interesting... In that case functional index should help (as it also makes statistic for the planner):

create index concurrently on task_task_execution_state_idx async.task using btree ((async.task_execution_state(task)));
analyze async.task;

Perhaps multicolumn index will also help for queries but hard to say without knowing distributions. We could check state distribution info after index creation and analyze with query like this:

select * from pg_stats where tablename = 'task_task_execution_state_idx' \gx


--

Alexey Ermakov

--------------d7KfeKs6elDgvnOG12QYy4lP--