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 1vrvJd-00D8LM-2A for pgsql-general@arkaria.postgresql.org; Mon, 16 Feb 2026 09:54:53 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.96) (envelope-from ) id 1vrvJc-000ekg-19 for pgsql-general@arkaria.postgresql.org; Mon, 16 Feb 2026 09:54:52 +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 1vrvJb-000ekS-37 for pgsql-general@lists.postgresql.org; Mon, 16 Feb 2026 09:54:52 +0000 Received: from mail-wm1-x342.google.com ([2a00:1450:4864:20::342]) by magus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (Exim 4.98.2) (envelope-from ) id 1vrvJZ-00000000zjk-3NcC for pgsql-general@lists.postgresql.org; Mon, 16 Feb 2026 09:54:51 +0000 Received: by mail-wm1-x342.google.com with SMTP id 5b1f17b1804b1-48371bb515eso32824895e9.1 for ; Mon, 16 Feb 2026 01:54:49 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=cybertec.at; s=google; t=1771235688; x=1771840488; darn=lists.postgresql.org; h=mime-version:user-agent:content-transfer-encoding:references :in-reply-to:date:cc:to:from:subject:message-id:from:to:cc:subject :date:message-id:reply-to; bh=fMa9TZ4vcORADudAHdJJMEF4HAj2vYtW7aQIkqGA8N8=; b=ZlQY81VTiomM5zzaROpdHcWCOO4zKoCwIZouHbOcrwV0k8xE8CKdeEI89Y1XZN0cQc AXY9rmOYcfbfp6CIJApaVVijmIYmgVRc8fjkSQqxolu86XpcGQ+lyNIQoGD21/lQeYJw FueoNwmLpKe+L+BaTA1eIWPEJfUex+teBQ/s5v6iWEad6EQ/MWXQ9QRixk7GeY/nq1qc GEyXQyCcTfzLFNQ90NOj5JxZqKG9XUrK4d4mX8pBcYljoPjHqMuMFFcAQLI/+SqBoqQg zH+zeJPjs26d9daaOjDW3WpYO7rGmysBIsdqAGnGi2IfiSAcwTMJKaaBCHJPwF8EPM/e 6xMg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1771235688; x=1771840488; h=mime-version:user-agent:content-transfer-encoding:references :in-reply-to:date:cc:to:from:subject:message-id:x-gm-gg :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=fMa9TZ4vcORADudAHdJJMEF4HAj2vYtW7aQIkqGA8N8=; b=XlLRDULFcYalWPWMBNBhsdRfwo+n4lAKrX1x0If+DBqxP009TfgruFJaf6IpQIravi /v/gqZZbzgRHit+IAbMk2hWIm1LpEDr1QCLHHGVl3fabzoJfGD0Yz+NJWJIMXOPmxSTn s9MixG3V4drakr+q3cOInIWJ4AF6taI2Q+V9tf49HxI6qFsX0dmUk+ZecDM6La1NxmTH AdyWus/kmCwYZrDMdYm4P/1vQeRpgWmOTof3lMvq2RwXtk4eIIy9AYHGv78egDT47EMv O8emM4vkt6QLrHdx7zG9rmjjIav4WhzBEpLoGla0m8pu60+Ag7DyXUAzgoclmFMuyEl3 DLkw== X-Gm-Message-State: AOJu0YwKzh33CcTVU0QLdrvqkGL2RMzHmA0NGsj4oY2Xw0HMXqvnoT4Q shpHUeBTFpewIPHbTeTf3EEnfcFJh5m1hNZxqHmwLyhEiAlP2VWd6c+wgET31NHnkqU= X-Gm-Gg: AZuq6aLFoA9JMn7T6zzushHucgN7q9+3FnGfIbgIcPixIvpkcBC9UML05RMKvFyvbTC Kgbsb0dYMejBKPQI3f2lc8WNa6rJVkp5MnpT3n0HSULsw490NlRN7Rt77bzk810W/ZbJRYlTOXV mgfHFViFplhmemQdgGxvpvacM2tHKbU6bkiqNifCsExLmwsMcwEt6IrQbP0Ol92VHYZNKnQTUWo yeL1YfX90BxY7wVZy1Jp5sNeDMShUpbi1IH8eEHI44Vyt5T0DZyFo9nwJB9KYb+W1UKVUUh2z2I bmx+VuNah9fIk+2MFtBHoUNftyCxAmL1OUGdp8PIoEfvvVb04IsgAT8CqBfkhC25tDQOBu75anb RxFhVENqE6jAfPfWm0N+z5o6Qg28HJoVYiZHwBylmVOlGs/rBSFvevoeTYYx27bbOQMlZrsBNu0 jBlDEJk+7/3xcPaPS9lgrOZM9iLuqg5Q6MqtbkPIs9gEg7PII6iq3YMn9Dk+qdpnM= X-Received: by 2002:a05:600c:4e4d:b0:483:498f:7963 with SMTP id 5b1f17b1804b1-48373a661ebmr161536885e9.26.1771235688216; Mon, 16 Feb 2026 01:54:48 -0800 (PST) Received: from laurenz.albe-K4N0CV00F97414D ([2001:871:70:b35f:c18e:4ea7:5f6d:fb6b]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-483709f8812sm142918975e9.0.2026.02.16.01.54.47 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 16 Feb 2026 01:54:47 -0800 (PST) Message-ID: <2fa62200cf92dc03dff20f8a42e45bb30fc40f35.camel@cybertec.at> Subject: Re: Question on execution plan and suitable index From: Laurenz Albe To: yudhi s , Ron Johnson , Adrian Klaver , Nisarg Patel Cc: pgsql-general Date: Mon, 16 Feb 2026 10:54:47 +0100 In-Reply-To: References: <818d0359d8b629a80b55b2e068dab958fc8e0a2a.camel@cybertec.at> Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable User-Agent: Evolution 3.58.3 (3.58.3-1.fc43) MIME-Version: 1.0 List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk On Mon, 2026-02-16 at 14:43 +0530, yudhi s wrote: > On Mon, Feb 16, 2026 at 2:29=E2=80=AFPM Laurenz Albe wrote: > > On Mon, 2026-02-16 at 00:34 +0530, yudhi s wrote: > > > It's postgres version 17. We are having a critical UI query which run= s for ~7 seconds+. The requirement is to bring down the response time withi= n ~1 sec. Now in this plan , If i read this correctly, the below section is= consuming a significant amount of resources and should be addressed. i.e. = "Full scan of table "orders" and Nested loop with event_audit_log table". > > >=20 > > > Below is the query and its complete plan:-=C2=A0 > > > https://gist.github.com/databasetech0073/f564ac23ee35d1f0413980fe4d00= efa9 > > >=20 > > > I am a bit new to the indexing strategy in postgres. My question is, = what suitable index should we create to cater these above? > > >=20 > > > 1)For table event_audit_log:- Should we create composite Index on col= umn (request_id,created_at,event_comment_text) or should we create the cove= ring index i.e. just on two column (request_id,created_at) with "include" c= lause for "event_comment_text". How and when the covering index indexes sho= uld be used here in postgres. Want to understand from experts?=C2=A0 > > > 2)Similarly for table orders:- Should we create a covering index on c= olumn (entity_id,due_date,order_type) with include clause (firm_dspt_case_i= d). Or just a composite index (entity_id,due_date,order_type). > > > 3)Whether the column used as range operator (here created_at or due_d= ate) should be used as leading column in the composite index or is it fine = to keep it as non leading? > > >=20 > > > -> =C2=A0Nested Loop =C2=A0(cost=3D50.06..2791551.71 rows=3D3148 widt= h=3D19) (actual time=3D280.735..7065.313 rows=3D57943 loops=3D3) > > > =C2=A0=C2=A0Buffers: shared hit=3D10014901 > > > =C2=A0=C2=A0-> =C2=A0Hash Join =C2=A0(cost=3D49.49..1033247.35 rows= =3D36729 width=3D8) (actual time=3D196.407..3805.755 rows=3D278131 loops=3D= 3) > > > =C2=A0Hash Cond: ((ord.entity_id)::numeric =3D e.entity_id) > > > =C2=A0Buffers: shared hit=3D755352 > > > =C2=A0-> =C2=A0Parallel Seq Scan on orders ord =C2=A0(cost=3D0.00..10= 22872.54 rows=3D3672860 width=3D16) (actual time=3D139.883..3152.627 rows= =3D2944671 loops=3D3) > > > =C2=A0=C2=A0Filter: ((due_date >=3D '2024-01-01'::date) AND (due_date= <=3D '2024-04-01'::date) AND (order_type =3D ANY ('{TYPE_A,TYPE_B}'::text[= ]))) > > > =C2=A0=C2=A0Rows Removed by Filter: 6572678 > > > =C2=A0=C2=A0Buffers: shared hit=3D755208 > >=20 > > You are selecting a lot of rows, so the query will never be really chea= p. > > But I agree that an index scan should be a win. > >=20 > > If the condition on "order_type" is always the same, a partial index is= ideal: > >=20 > > =C2=A0 =C2=A0CREATE INDEX ON orders (due_date) WHERE order_type IN ('TY= PE_A', 'TYPE_B'); > >=20 > > Otherwise, I'd create two indexes: one on "order_type" and one on "due_= date". >=20 > Version is 17.7. Below is the table definitions as i pulled from Dbeaver = tool:- >=20 > https://gist.github.com/databasetech0073/f22d95de18dc3f1fa54af13e7fd2ce9e= =C2=A0 >=20 > The Order_type will be TYPE_A and TYPE_B in most of the cases. And below = is the distribution. > So , it looks like the index on this column will not help much. Correct m= e if I'm wrong. >=20 > TYPE_A 25 Million > TYPE_B 2 Million > TYPE_C 700K > TYPE_D 200K > TYPE_E 6k No, you are right about that. > I am wondering why the already=C2=A0existing index on column "due_date" o= f table "order" is not > getting used by the optimizer? Should we also add the column "entity_id" = to the index too? Seeing that your execution plan is incomplete, it is hard to say anything a= bout that. The scans of "entities" are missing, as is the UNION. > And, Yes there are differences in data types of the "entity_id" for colum= ns of table "order" > and "entity". We need to fix that after analyzing the data. >=20 > Also the highlighted Nested loop above shows ~10M shared hits (which will= be ~70GB+ if we > consider one hit as an 8K block). So does that mean , apart from the Full= scan on the "order" > table , the main resource consuming factor here is the scanning of "event= _audit_log". Correct. Yours, Laurenz Albe