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 1tsdF8-003lBl-IH for pgsql-performance@arkaria.postgresql.org; Thu, 13 Mar 2025 07:44:39 +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 1tsdE8-006poE-VN for pgsql-performance@arkaria.postgresql.org; Thu, 13 Mar 2025 07:43:36 +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 1tsZpO-002yDp-Gl for pgsql-performance@lists.postgresql.org; Thu, 13 Mar 2025 04:05:51 +0000 Received: from sonic314-15.consmr.mail.bf2.yahoo.com ([74.6.132.125]) by magus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (Exim 4.96) (envelope-from ) id 1tsZpJ-002Zc0-1p for pgsql-performance@postgresql.org; Thu, 13 Mar 2025 04:05:50 +0000 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ymail.com; s=s2048; t=1741838743; bh=l2cRUkGFhfYpNYyY9EYxjjmmx5QnxpricTwCf+bR9so=; h=From:To:Subject:Date:References:From:Subject:Reply-To; b=TmTtHTNF0PhiQ1sy7rxEimuKhBb7cKWDgQ8PzK3fdMywpV1sEyXUSX3aFTUl/repk/zlM4EgQdFKYC32AwKQYVVDU5c/sbGXptpb0qf0L48/kgUlz204YOBgJW1t02SsVKmvU7HE6B4QniG5i0jArI9/f6mY9BGi2TB6bVEGDAG1eQle4ygettiBGXxLFgD/VR2qH/LIeSWz6sHxn8cej0yl+pVMaYBEYUHqSgs/hoQhMGntTOAn/OFU/UYHwHYmXEPDl4sDwnEkz0lZ8K81UGFprnXUvDrNlhqSd1jod1Sp8tEwYQ0Jc93AYUiM9WdumeQUvhoc0LOHxr2aw/dyOg== X-SONIC-DKIM-SIGN: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1741838743; bh=koep3UVThW799rghu3TmDHS/LZtieZZoQscCKq1eTDV=; h=X-Sonic-MF:From:To:Subject:Date:From:Subject; b=iF7gZkrUvzWUPBa3E1TxQSNZA7XtQ3gXV194yE19FaDjCR3JIdrChlx+XgK4q8ZvfcxuWso728QpYwe7m90ulwtCPCrgduk4ecIG/nO0isyKw90nWmDELlogNllOyYuBBWxc0ycnhF9IBtlJGqAtWTHu/SY6ZsPcZ2UTrToCgrNNUoHYyS2apKuHQ6e9p7nAEny6GgPnUheLkQzF5ETCDxy0wk4XOHJ7rLkfdUO7rreyUkh+boSdhY1U7Qzdzxhh9Rfp/tbGyny5lajWe2EdvWl4O3WIVC/Eirq39UYzI4BR525JVMVg6+fpZVC4RR+tPtZo2DwsPFA6t52x1pVGTg== X-YMail-OSG: Xm6tVeIVM1kcjPSVRjJgEQlhw8BjL.yoKEEvcPkrGUNKz3NVyUZzj_Fd64A8TmJ JhOr4AEElNZZji1SEKZNlVhBdTjsUL_8w0YyLEgCX0mDE_ZArSPnRgC00NRcHZRO6QVmkS5vneoX SgZGMJG8z3lOA5ec09aXRcodtQnbHypsMqm1ppWhDrt_itkuoDrBtrlOd9kLAFDL5wQFKqJ121yK zboGJ9H7QrPN_YW5Ha4n7213Xt7HRLWmJt1POR9spx1seZwOupk.r5m_ooFqpMMEbr.Dmtcm331L j9JQcElcF19wYUH5taJ__Jx4t1oL7htDcEy0IcmbPi4QrqIt58hWKJb6B.c1veS7HMMd0i29VMMG _ZnKtj30sRkFhntn6PtHb5dxroLGpeb4lduyJkMis3Dti7IgCRi5e3T5AXVcBCCXNnOX7KmS0QjQ dNfGprb_QtPwpEw5P83TLcKE7dWr8DHrD4rR0S3Esw_rKHKzwMuJgkmIVfZgUa4HAYLoGC6z4Wmv vp.IqW5cyQY1q4D306KRdeTorht9V9DgN7B.pJCBF_4WLtBWQfCUfladGGMED_XWT6i6FJYSA6.j _fP.2zjI1GZzb5UF_yLJgjbCmq2NZbKBsLCQ.ZKBZgJaVSOIXUkcCPS8vX0T.xKa.EtIirSnoIux jD8KkVgZcKahF5GZbWLTLL47vIWcjRBVL477beVijuPcBPVnAdKq2w.jw0B.3dzPbbMmIawmRkNf p4v7gbu8txu2zE5AIknZnEVJxD4TQ1QyS41iFzXsEyI3frOS.UeCxd19eOMEL75OEHE66.Mldow4 3ttfTTqcPcp5GpjFQh3cHiDmTcjsbN4UdoSsW6t8moyHopAfeWfnUUyV.a_rtAFwQB5r0XzTKQk2 efumFtI43gQTEkGzwVMIz7mQ1t4b9QH0J46afm6i3tHldkqAzh1y2C2CoTQXUTlSRTTDFSdKGiT9 gUzI5GG9TWdy36LM8cAotO1Kbix99m02jzb9sKjI9yMeKg5HOgB_P3jvFeSOJ8Orxf42r3jEa6Db Ny9WNIT3t68qjRHo5GFg89_e1SL0L3ge5Ff4iCiDzJhlpuFcn8EWF4t_NhjWb9c15G_66DgPjRCH lN6Zzs_QS4p2OlaaXXjywCvkweCc5FcP.WxxrVBHzxi.xlkiL9bq0ueeZ_eT9SO1uGwZjS6c3T7W 7jpZ3V9huC5Nnt9bE.Wuv4m.OSs9F_3_53gAk6KdnMZMQJmDvWpMMmLMjF6twD9OFmHI3c0eFU0z Yck1Dvxf2LbDWHabvCAFurUthV7xj3RafRjXKZhiwwA_2KEPDCA6NbLWrp2ZgVnvPbFE0QlYXLBU 53Wv.WH83NoIu9LIsT_cTaZ4Jvj1eqtDz.CscAaTuiEDbTUrA7npKzUUtm.2hXUICarcZ2l1l8F7 gL1tP98h.UJOO.lPIbrPuVxw4Zgc_3vrl..X1LpZDuK4slZFboNlpFSRXl6zysrtjWiQmpkVRUUA FXzfETLd.9IoOZE9vGEOXK3M1ROLURWbEIj3dP_4oIv6LJekZFZUf.qMNIelO9WqL.ug.bNayskQ yp3WdQUS5OH4eJuXumZECrd_iMGoNNnBJ3ApRXk.G8MkyqQ09f.2tSv1mw7bPngIR94Lpzc0wEDS OSS69aAD9SUrIO82ChialQ4NWXc1mOgzhs4AVp5TCtxd2hFH22P2eF5hbglGcOs1eCBn2sqobKDo SHETpX3T_vZN5gjuSP9uoCZ3PULFP_qzQqizs8jYgvX0GNFvbNdgBbtOPtlvaelnO4byV.iKYnOi XKr7YprDDMteauUdkt_2j9bKKLRni2myLGDBrH5WwrK3Mf9_0PF6Hb86n9ngwWRAgKUsepwNdzQ2 Po.PFSADRnAMFF5GZuvbE4w1QzhwxcNmGIHzjmEqruiWXaZVQyj46ebY_iEU5607tYZhQwqFEL4b 4b0BgAmPDAIqkPn3GIOySXwvuYgjvSa7YdDVNM_5KhQoDRFLwZOimuXVEFtjvWRG9M1ptFflZUBB ewbT0LnxmVTSP6a.T13btFuV3fA4xifcWZpt5GOvSgX5IIKMKIWB62VXluYtrU.B17l8Bj9_ALgl B3.JjSLJ5tFOjA0bkJ5_1sxS0h3udQPSc5N9w.pPHEK2P_gjT6rh8cltfIltZsaSy8xTlyywgIea gC9WSSrtvxXFTrECUUI3EugUnTizR6oTzO86_dsnWESU0FZ1OUD3ZEuZ7rOtuGAkUJ4HDiQSRxOp _G4olbHtHyx8ShsrItrifZEkNOSoN348zG_Xnk4c- X-Sonic-MF: X-Sonic-ID: 91ead3cb-330a-4478-944c-4156778eff95 Received: from sonic.gate.mail.ne1.yahoo.com by sonic314.consmr.mail.bf2.yahoo.com with HTTP; Thu, 13 Mar 2025 04:05:43 +0000 Received: by hermes--production-gq1-7d5f4447dd-9qjv2 (Yahoo Inc. Hermes SMTP Server) with ESMTPA ID 452ecf23791b26ffb0432ec4903288da; Thu, 13 Mar 2025 04:05:40 +0000 (UTC) From: To: Subject: Bulk DML performance Date: Thu, 13 Mar 2025 12:05:34 +0800 Message-ID: <008701db93cd$2eb404d0$8c1c0e70$@ymail.com> MIME-Version: 1.0 Content-Type: multipart/alternative; boundary="----=_NextPart_000_0088_01DB9410.3CD744D0" X-Mailer: Microsoft Outlook 16.0 Thread-Index: AduTwtnms/JVVmIRR2uvT32rK3gn8w== Content-Language: en-au References: <008701db93cd$2eb404d0$8c1c0e70$.ref@ymail.com> Content-Length: 7157 List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk This is a multipart message in MIME format. ------=_NextPart_000_0088_01DB9410.3CD744D0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Hello! I'm building a system that needs to insert/update batches of millions of rows (using INSERT .. ON CONFLICT (.) DO UPDATE) in a single database transaction, where each row is about 1.5 kB. The system produces about 3 million rows (about 4.5 GB) of data in about 5 seconds, but PostgreSQL takes about 35 seconds to insert that data and about 55 seconds to update that data. This is both on my local dev machine as well as on a large AWS Aurora PostgreSQL instance (db.r8g.16xlarge with 64 vCPUs, 512 GB RAM and 30 Gbps). The following INSERT .. ON CONFLICT (.) DO UPDATE statement inserts/updates 3 million rows with only 9 bytes per row and takes about 8 seconds on first run (to insert the rows) and about 14 seconds on subsequent runs (to update the rows), but is only inserting 27 MB of data (3 million rows with 9 bytes per row); although after the first run, SELECT pg_size_pretty(pg_total_relation_size('test')) reports the table size as 191 MB and after the second run reports the table size as 382 MB (adding another 191 MB). CREATE TABLE test ( id bigint PRIMARY KEY, text1 text ); INSERT INTO test (id, text1) SELECT generate_series, 'x' FROM generate_series(1, 3000000) ON CONFLICT (id) DO UPDATE SET text1 = 'x'; If PostgreSQL is writing 191 MB on the first run and 382 MB on each subsequent run, then PostgreSQL is only writing about 28 MB/s. Although PostgreSQL is also able to write about 4.5 GB in about 35 seconds (as stated above), which is about 128 MB/s, so it seems the performance constraint depends on the number of rows inserted more than the size of each row. Furthermore, deleting the rows takes about 18 seconds to perform (about 4 seconds longer than the time taken to update the rows): DELETE FROM test WHERE id in ( SELECT * FROM generate_series(1, 3000000) ) It seems like it should be possible to do better than this on modern hardware, but I don't have enough knowledge of the inner workings of PostgreSQL to know whether my instinct is correct on this, so I thought I'd raise the question with the experts. Thanks! Bill ------=_NextPart_000_0088_01DB9410.3CD744D0 Content-Type: text/html; charset="us-ascii" Content-Transfer-Encoding: quoted-printable

Hello! I’m building a = system that needs to insert/update batches of millions of rows (using = INSERT .. ON CONFLICT (…) DO UPDATE) in a single database = transaction, where each row is about 1.5 kB. The system produces about 3 = million rows (about 4.5 GB) of data in about 5 seconds, but PostgreSQL = takes about 35 seconds to insert that data and about 55 seconds to = update that data. This is both on my local dev machine as well as on a = large AWS Aurora PostgreSQL instance (db.r8g.16xlarge with 64 vCPUs, 512 = GB RAM and 30 Gbps).

 

The = following INSERT .. ON CONFLICT (…) DO UPDATE statement = inserts/updates 3 million rows with only 9 bytes per row and takes about = 8 seconds on first run (to insert the rows) and about 14 seconds on = subsequent runs (to update the rows), but is only inserting 27 MB of = data (3 million rows with 9 bytes per row); although after the first = run, SELECT pg_size_pretty(pg_total_relation_size('test')) reports the = table size as 191 MB and after the second run reports the table size as = 382 MB (adding another 191 MB).

 

CREATE TABLE = test (

  id bigint PRIMARY = KEY,

  text1 = text

);

 

INSERT INTO = test (id, text1)

SELECT = generate_series, 'x'

FROM = generate_series(1, 3000000)

ON = CONFLICT (id) DO UPDATE

SET text1 =3D = 'x';

 

If PostgreSQL is writing 191 MB on the first run and = 382 MB on each subsequent run, then PostgreSQL is only writing about 28 = MB/s. Although PostgreSQL is also able to write about 4.5 GB in about 35 = seconds (as stated above), which is about 128 MB/s, so it seems the = performance constraint depends on the number of rows inserted more than = the size of each row.

 

Furthermore, = deleting the rows takes about 18 seconds to perform (about 4 seconds = longer than the time taken to update the rows):

 

DELETE FROM = test

WHERE id in (

  SELECT * FROM generate_series(1, = 3000000)

)

 

It seems = like it should be possible to do better than this on modern hardware, = but I don’t have enough knowledge of the inner workings of = PostgreSQL to know whether my instinct is correct on this, so I thought = I’d raise the question with the experts.

 

Thanks!

Bill

------=_NextPart_000_0088_01DB9410.3CD744D0--