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 1sgNGt-001K32-1G for pgsql-general@arkaria.postgresql.org; Tue, 20 Aug 2024 11:43:31 +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 1sgNGr-00FXA0-1A for pgsql-general@arkaria.postgresql.org; Tue, 20 Aug 2024 11:43:29 +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 1sgNGq-00FX9s-MK for pgsql-general@lists.postgresql.org; Tue, 20 Aug 2024 11:43:29 +0000 Received: from mail-lf1-x12b.google.com ([2a00:1450:4864:20::12b]) by magus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (Exim 4.94.2) (envelope-from ) id 1sgNGn-000bbE-7l for pgsql-general@lists.postgresql.org; Tue, 20 Aug 2024 11:43:28 +0000 Received: by mail-lf1-x12b.google.com with SMTP id 2adb3069b0e04-5333b2fbedaso2476070e87.0 for ; Tue, 20 Aug 2024 04:43:26 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1724154206; x=1724759006; darn=lists.postgresql.org; h=content-transfer-encoding:cc:to:subject:message-id:date:from :in-reply-to:references:mime-version:from:to:cc:subject:date :message-id:reply-to; bh=PlqaAGnqqoKIhfeETysvgtbK4vFY2/7/+jgYa1ieZUw=; b=ncYYr5OCzu2hq0GmP1mkp3FnsIZ3LaLkTP6tZfAFcrqj+gub5N2h4Xq5Qv5eL1PchL 4iBUrsAdXMFW5sBO541ntyJmq2X4RFo1sK7g6SLb8BIulSb9bBwM5uS7ENaFKU8XoOAl HFtWTfRkupP/Yv7hxHg0olEpjcVy6H0U2AvFuTKyrbL5qL77ZG2ncqB8/0RQDM+tFgKP 0XDR7WrBjjKbXlq+b5Y6ruxFLg121bi3PL+Q5m09weYykqxNQyY2A79C+7/VsYGCGJCs Gao2771FZNbyf5mFkgUneDk3HxeuVEXsm3o+TkLGJT6lXFKS7CM6Zd1mB739cYUIjqCm K9eA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1724154206; x=1724759006; h=content-transfer-encoding:cc:to:subject:message-id:date:from :in-reply-to:references:mime-version:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=PlqaAGnqqoKIhfeETysvgtbK4vFY2/7/+jgYa1ieZUw=; b=KrpnRZ2X738fpJHyjNbSnLY3ICqRxzI6nuxVQFUNNYSmXAysWB55Xe4YZv5CEq1iiD K4QROuJ5sxSXt5Vr3/CUozBtjid4E5Xie5o/7rQNRuVQjaAsAZzhsLwVR9KYPDGda2we vXfT0StkrdyfOH79X/FIMdjoG9zO0z6ThAMi6UZdbhELXYAOkyNEAdo8gtg+sQoUxNwi GlK2zZ01AQ/Swk1wRz1YoqwZ3hnPaGc9C3ePN5QBZsZNBRvwK/0aIVH4O6EB9uca7jo8 ETWJyuV+A2omkNTUSB8vlgDLM8dssd04f6o9PhjRxUIapKD++/KPWfe3u5Qe/wr3Sqzy sS+Q== X-Gm-Message-State: AOJu0YzxmpjAnjIE3tIeEgm4jQxEsQSJ2Wf09wjJYp4nL2Wvm69IgeAI dKwSRsc8FNJOPrE/uHg0ok8aRulSvWiLWJ6rLps/0hIpjiNdfKXXML4vxr5hDjcz+E51LJb0x4+ rmtoXIys+uIKohFGDMrXoOEFC8ZiQi447 X-Google-Smtp-Source: AGHT+IEHm+ffxdEhKhJkrqBmRGKqbGv5w1LHHM0UAuTdWrexqV2cU7bxeaNtPr/oFjVgsMytZt3JwV/ywe/1/0yfcbw= X-Received: by 2002:a05:6512:2355:b0:52c:9383:4c16 with SMTP id 2adb3069b0e04-5331c6a3b65mr9059794e87.22.1724154205355; Tue, 20 Aug 2024 04:43:25 -0700 (PDT) MIME-Version: 1.0 References: In-Reply-To: From: David Rowley Date: Tue, 20 Aug 2024 23:43:13 +1200 Message-ID: Subject: Re: Insert query performance To: sud Cc: pgsql-general Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk On Tue, 20 Aug 2024 at 19:09, sud wrote: > However, my initial understanding of "having the FK index will improve th= e insert performance in the child table" is not accurate it seems. Rather a= s you mentioned it may negatively impact the loading/insert performance bec= ause it has to now update the additional index in each insert. In case of i= nsert into child table, to ensure if the child row is already present in th= e parent , it just scans the parent by the Primary key of the parent table= (which is be default indexed) and thus it doesn't need an index in the chi= ld table foreign keys or having an index in the foreign key in the child ta= ble won't help the constraint validation faster. Please correct me if my un= derstanding is wrong here. If you think about what must happen when you insert into the referencing table, the additional validation that the foreign key must do is check that a corresponding record exists in the referenced table. An index on the referencing table does not help speed that up. > Additionally as you mentioned "explain analyze" will show a section on ho= w much time it really takes for the constraint validation , I can see that = section now. But it seems it will really need that INSERT statement to be e= xecuted and that we can't really do in production as that will physically i= nsert data into the table. So do you mean to just do the "explain analyze" = for the INSERT query and capture the plan and then do the rollback? And in= our case it's a row by row insert happening , so we will see if we can clu= b/sum that "constraint validation" time for a handful if insert somehow to = get a better idea on the percentage of time we really spent in the constrai= nt validation. I'd recommend performing a schema-only dump of your production database and experimenting well away from production. See pg_dump --schema-only. I also recommend not leaving performance to chance and testing the impact of index vs no index away from production with some data loaded that is representative of your production data (or use the production data if it's available and small enough to manage). Use pgbench to see what impact having the index on the referencing table has on performance on inserts into that table vs what improvements you gain from having the index when there's cascading delete from the referenced table. You might also want to look into auto_explain [1]. You can load this into a single session and set auto_explain.log_min_duration =3D 0, auto_explain.log_analyze =3D on and auto_explain.log_nested_statements =3D on. That should give you the plan for the cascade DELETE query that's executed by the trigger when you perform the DELETE on the referenced table. (Also see the note about auto_explain.log_timing) David [1] https://www.postgresql.org/docs/15/auto-explain.html