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 1r8Udu-00A8yb-9R for pgsql-hackers@arkaria.postgresql.org; Thu, 30 Nov 2023 00:10:58 +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 1r8Udr-00DkAL-TT for pgsql-hackers@arkaria.postgresql.org; Thu, 30 Nov 2023 00:10:55 +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 1r8Udr-00Dk9t-I0 for pgsql-hackers@lists.postgresql.org; Thu, 30 Nov 2023 00:10:55 +0000 Received: from mail-wr1-x436.google.com ([2a00:1450:4864:20::436]) by magus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (Exim 4.94.2) (envelope-from ) id 1r8Udn-009FkV-Su for pgsql-hackers@lists.postgresql.org; Thu, 30 Nov 2023 00:10:54 +0000 Received: by mail-wr1-x436.google.com with SMTP id ffacd0b85a97d-33319741ba0so311831f8f.1 for ; Wed, 29 Nov 2023 16:10:51 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=enterprisedb.com; s=google; t=1701303050; x=1701907850; darn=lists.postgresql.org; h=content-transfer-encoding:in-reply-to:from:references:cc:to :content-language:subject:user-agent:mime-version:date:message-id :from:to:cc:subject:date:message-id:reply-to; bh=tIg2mtdkVeANIqVFSRJWA/7lW0IUOGRZaChC6Cait1Y=; b=V6pZetXMxtBQIvNjXOOPCSa8Mp8ypMmfSAG9ZrvepJJN1KQPjBEdesSXG5kMIDfIeG suzptxVPqkzzlwLR9h9HVm8+Q+zgL9n0Q/nDzHR0DRas/pausU1sKhzj3KUBiW4x9kP/ Z1PewRrrZG4ADXOQS+kwMjheL0QD1Mr0qIblmQvUYaBvDLvOiz7M2DCGluedfoR+yrpV MC9qmGDvd0JhK1k6s0aFVKUHMZWyZrMACX72E8bQvutjUYritjjB/jdteGPqg5j1eF3e lGIsRQxa+lD8GShNy0JmD3BvUDTM1p2SDsnRfOxUxUqw1FBK1QkAjfgzy9CwIqzkeono EiyA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1701303050; x=1701907850; h=content-transfer-encoding:in-reply-to:from:references:cc:to :content-language:subject:user-agent:mime-version:date:message-id :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=tIg2mtdkVeANIqVFSRJWA/7lW0IUOGRZaChC6Cait1Y=; b=okeAbKZpK8pPJaBmh3ouxe9Lut0LWoq/fc1KG5FD0gxvXtebU1PO3cse/3FNeEuvTP dBcW6tnrqI/ZazRjneckIYV6FSk9MyMn/hnqlRsfWosbC15l++G3oB3sgTbATgILLug6 hjvpkksmnMZlaEOtLSRKiAdO9ioWypvbsIMOXPwG+J7cj2IFY61WvpdHpOFYD0A3EgrK k0eoImG08nE5k5zQg3+dZ6Jlq8rXK4Qq/1a2efsnL7qtkPlA6Zaqe0itV5NYtZMwSMGf +kPs75Uv/YDFli02g+jpt9ofrSKxDENd+4woA6rb5lfpFzmS3t0gy2+dDvtm2oQ9jzQO jCPA== X-Gm-Message-State: AOJu0Yw8NY6bzKwUrxVyWJqjj6PEHQ5M3N28MSloc40IjwYrarVHuzyL 1CoqS3kkr1bb8PW3OKEHlWgB0w== X-Google-Smtp-Source: AGHT+IH062xeUojZO+tKF2tSPyZ0hRExNPvfP0mCDs40TKpkiCKS/d+PYZxsOESj8M4EuVaMtJhGxw== X-Received: by 2002:a05:6000:1364:b0:332:e667:4277 with SMTP id q4-20020a056000136400b00332e6674277mr13190325wrz.40.1701303050255; Wed, 29 Nov 2023 16:10:50 -0800 (PST) Received: from [10.137.0.17] (ip-86-49-225-170.bb.vodafone.cz. [86.49.225.170]) by smtp.gmail.com with ESMTPSA id fa10-20020a05600c518a00b00405442edc69sm3734553wmb.14.2023.11.29.16.10.49 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Wed, 29 Nov 2023 16:10:49 -0800 (PST) Message-ID: Date: Thu, 30 Nov 2023 01:10:48 +0100 MIME-Version: 1.0 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:102.0) Gecko/20100101 Thunderbird/102.15.1 Subject: Re: Parallel CREATE INDEX for BRIN indexes Content-Language: en-US To: Matthias van de Meent Cc: PostgreSQL Hackers References: <2e86059f-4004-eec1-2bc1-9e7fd119c9e2@enterprisedb.com> <5384d42e-1961-c2fd-1955-1a5a99fa1234@enterprisedb.com> <9a646c51-a4c3-ce34-cccd-99d00fd1dc6a@enterprisedb.com> <64adb9cb-3474-e0ff-7a38-9bed4f5170e6@enterprisedb.com> From: Tomas Vondra In-Reply-To: Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 7bit List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk On 11/29/23 23:59, Matthias van de Meent wrote: > On Wed, 29 Nov 2023 at 21:56, Tomas Vondra > wrote: >> >> On 11/29/23 21:30, Matthias van de Meent wrote: >>> On Wed, 29 Nov 2023 at 18:55, Tomas Vondra >>> wrote: >>>> I did try to measure how much it actually saves, but none of the tests I >>>> did actually found measurable improvement. So I'm tempted to just not >>>> include this part, and accept that we may deserialize some of the tuples >>>> unnecessarily. >>>> >>>> Did you actually observe measurable improvements in some cases? >>> >>> The improvements would mostly stem from brin indexes with multiple >>> (potentially compressed) by-ref types, as they go through more complex >>> and expensive code to deserialize, requiring separate palloc() and >>> memcpy() calls each. >>> For single-column and by-value types the improvements are expected to >>> be negligible, because there is no meaningful difference between >>> copying a single by-ref value and copying its container; the >>> additional work done for each tuple is marginal for those. >>> >>> For an 8-column BRIN index ((sha256((id)::text::bytea)::text), >>> (sha256((id+1)::text::bytea)::text), >>> (sha256((id+2)::text::bytea)::text), ...) instrumented with 0003 I >>> measured a difference of 10x less time spent in the main loop of >>> _brin_end_parallel, from ~30ms to 3ms when dealing with 55k 1-block >>> ranges. It's not a lot, but worth at least something, I guess? >>> >> >> It is something, but I can't really convince myself it's worth the extra >> code complexity. It's a somewhat extreme example, and the parallelism >> certainly saves much more than this. > > True. For this, I usually keep in mind that the docs on multi-column > indexes still indicate to use 1 N-column brin index over N 1-column > brin indexes (assuming the same storage parameters), so multi-column > BRIN indexes should not be considered to be uncommon: > > "The only reason to have multiple BRIN indexes instead of one > multicolumn BRIN index on a single table is to have a different > pages_per_range storage parameter." > > Note that most of the time in my example index is spent in creating > the actual tuples due to the use of hashing for data generation; for > index or plain to-text formatting the improvement is much more > pronounced: If I use an 8-column index (id::text, id, ...), index > creation takes ~500ms with 4+ workers. Of this, deforming takes some > 20ms, though when skipping the deforming step (i.e.,with my patch) it > takes ~3.5ms. That's a 3% shaved off the build time when the index > shape is beneficial. > That's all true, and while 3.5% is not something to ignore, my POV is that the parallelism speeds this up from ~2000ms to ~500ms. Yes, it would be great to shave off the extra 1% (relative to the original duration). But I don't have a great idea how to do code that in a way that is readable, and I don't want to stall the patch indefinitely because of a comparatively small improvement. Therefore I propose we get the simpler code committed and leave this as a future improvement. >>> The attached patch fixes the issue that you called out . >>> It also further updates _brin_end_parallel: the final 'write empty >>> tuples' loop is never hit and is thus removed, because if there were >>> any tuples in the spool we'd have filled the empty ranges at the end >>> of the main loop, and if there were no tuples in the spool then the >>> memtuple would still be at its original initialized value of 0 thus >>> resulting in a constant false condition. I also updated some comments. >>> >> >> Ah, right. I'll take a look tomorrow, but I guess I didn't realize we >> insert the empty ranges in the main loop, because we're already looking >> at the *next* summary. > > Yes, merging adds some significant complexity here. I don't think we > can easily get around that though... > >> But I think the idea was to insert empty ranges if there's a chunk of >> empty ranges at the end of the table, after the last tuple the index >> build reads. But I'm not sure that can actually happen ... > > This would be trivial to construct with partial indexes; e.g. WHERE > (my_pk IS NULL) would consist of exclusively empty ranges. > I don't see a lot of value in partial BRIN indexes, but I may be > overlooking something. > Oh, I haven't even thought about partial BRIN indexes! I'm sure for those it's even more important to actually fill-in the empty ranges, otherwise we end up scanning the whole supposedly filtered-out part of the table. I'll do some testing with that. regards -- Tomas Vondra EnterpriseDB: http://www.enterprisedb.com The Enterprise PostgreSQL Company