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 1s59PE-003YRF-Vk for pgsql-hackers@arkaria.postgresql.org; Thu, 09 May 2024 19:26:17 +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 1s59PC-009wZH-Kh for pgsql-hackers@arkaria.postgresql.org; Thu, 09 May 2024 19:26:14 +0000 Received: from makus.postgresql.org ([2001:4800:3e1:1::229]) by malur.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.94.2) (envelope-from ) id 1s59PC-009wZ8-5s for pgsql-hackers@lists.postgresql.org; Thu, 09 May 2024 19:26:14 +0000 Received: from mail-lj1-x234.google.com ([2a00:1450:4864:20::234]) by makus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (Exim 4.94.2) (envelope-from ) id 1s59P6-000DkL-LX for pgsql-hackers@lists.postgresql.org; Thu, 09 May 2024 19:26:12 +0000 Received: by mail-lj1-x234.google.com with SMTP id 38308e7fff4ca-2e0a0cc5e83so18721161fa.1 for ; Thu, 09 May 2024 12:26:08 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=enterprisedb.com; s=google; t=1715282766; x=1715887566; darn=lists.postgresql.org; h=content-transfer-encoding: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=BwF3xPSybyaMT/aT0Z3iOXJlIJ50lvSTKe+C54W64VY=; b=JOybvX3adWQvPkuGFJ+0LBVgXOy5fLQqvfU3sBGznrBUGiaww7xvHFdgH1Yo2uOPr6 mqS8zCdkaY/GiVpBkPuQBNF5Hmz9d0qIPaTFDYI2GGbmbtfIv14PTvopXHZrDKAruyX1 n2tjwm562aLjahkV+/2TUn4ucMhB18W9bdoOIxBEBYnSzueBFD5YkIfI0SlN20R3YrbR VSvM0lSJ8TKvVUc6vdpxcgo+L0fNtuv732WIs/0Xo/iTR/4GLJ2V+V/2XH9RYor1S0gr bk/HsE6if8VBIIgvBzebeE4TjIkcMq7aIg48+gAVD1GX1PFLNr+Ajk7s3sGwOTNm0J4n aLNw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1715282766; x=1715887566; h=content-transfer-encoding:in-reply-to:from:content-language :references:cc:to:subject:user-agent:mime-version:date:message-id :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=BwF3xPSybyaMT/aT0Z3iOXJlIJ50lvSTKe+C54W64VY=; b=OPTvYd0CeLeLYGAFwZiN0vk3MRiApUZ6t0ViQ5OoOj1SyagxDHBtSuAiJ8y7HwOR+q qZ0EECIohGlrmQRA5lwxayJyCIjWzkioqs+9PnNQCZCUp/ruw+FPUzhvzM8f1dPpbqek fOMgyoqdutgXzlSRWaR3kdJ1xacaSZFNYT+bSaku6ApPGPIzMgMEr9KjckOv+cW74MlF UoKf3Iuwo8u1HvuchjU5JF9SkEn07PHNNf8OjwDuKuzkmN2/FK/SCURl7aGiFGYs7y9W Nkdot0f8jg/doTIs+Mi6sfggMWZ0twgFQNqup2qq8Ok7TlSOqR0ePdg1FNGoCdkaQ9Ib RSOg== X-Forwarded-Encrypted: i=1; AJvYcCUpxq/Wpif22merWYNzl21pYFiUtmrF5LofhUfcwWMHp5t/gUaGh1vsMb2HqrK9JKwTbhhq0e4OkNUwXSZtaodgFbnm+sJK/ig6uJ1WhJ3ioEf9 X-Gm-Message-State: AOJu0Yyr/I/mcMFHvfAoDZvhj/+6exKMBBeZ59YAnenI2PmqoTR33c3s gBvGlA+zHZM06Y857Mihh4rzTGzz6lrs3niX0lnpigfgFkMITQLPlvxXAyRBccHeYosdaxDI5fg = X-Google-Smtp-Source: AGHT+IEt9MmqImtPFKCYPDk9QfNItPPSFkLCfQIE/YuIqKDKxk7zPupUMVgzZFAlmaXrB5nCOnLkdw== X-Received: by 2002:a2e:720d:0:b0:2e0:69b4:d655 with SMTP id 38308e7fff4ca-2e51fe52731mr2437181fa.3.1715282765632; Thu, 09 May 2024 12:26:05 -0700 (PDT) Received: from [10.137.0.18] (ip-86-49-229-30.bb.vodafone.cz. [86.49.229.30]) by smtp.gmail.com with ESMTPSA id 4fb4d7f45d1cf-5733bea653bsm1011685a12.1.2024.05.09.12.26.05 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Thu, 09 May 2024 12:26:05 -0700 (PDT) Message-ID: Date: Thu, 9 May 2024 21:26:04 +0200 MIME-Version: 1.0 User-Agent: Mozilla Thunderbird Subject: Re: Parallel CREATE INDEX for GIN indexes To: Matthias van de Meent Cc: Andy Fan , pgsql-hackers@lists.postgresql.org References: <6ab4003f-a8b8-4d75-a67f-f25ad98582dc@enterprisedb.com> <5b5a059d-0699-4cc2-b9a0-32053ea19a65@enterprisedb.com> <87ttj7mhib.fsf@163.com> <5de12918-c1bc-4639-80c8-f06d2a8c95e3@enterprisedb.com> Content-Language: en-US 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 5/9/24 17:51, Matthias van de Meent wrote: > On Thu, 9 May 2024 at 15:13, Tomas Vondra wrote: >> Let me explain the relevant part of the patch, and how I understand the >> improvement suggested by Matthias. The patch does the work in three phases: >> >> >> 1) Worker gets data from table, split that into index items and add >> those into a "private" tuplesort, and finally sorts that. So a worker >> may see a key many times, with different TIDs, so the tuplesort may >> contain many items for the same key, with distinct TID lists: >> >> key1: 1, 2, 3, 4 >> key1: 5, 6, 7 >> key1: 8, 9, 10 >> key2: 1, 2, 3 >> ... > > This step is actually split in several components/phases, too. > As opposed to btree, which directly puts each tuple's data into the > tuplesort, this GIN approach actually buffers the tuples in memory to > generate these TID lists for data keys, and flushes these pairs of Key > + TID list into the tuplesort when its own memory limit is exceeded. > That means we essentially double the memory used for this data: One > GIN deform buffer, and one in-memory sort buffer in the tuplesort. > This is fine for now, but feels duplicative, hence my "let's allow > tuplesort to merge the key+TID pairs into pairs of key+TID list" > comment. > True, although the "GIN deform buffer" (flushed by the callback if using too much memory) likely does most of the merging already. If it only happened in the tuplesort merge, we'd likely have far more tuples and overhead associated with that. So we certainly won't get rid of either of these things. You're right the memory limits are a bit unclear, and need more thought. I certainly have not thought very much about not using more than the specified maintenance_work_mem amount. This includes the planner code determining the number of workers to use - right now it simply does the same thing as for btree/brin, i.e. assumes each workers uses 32MB of memory and checks how many workers fit into maintenance_work_mem. That was a bit bogus even for BRIN, because BRIN sorts only summaries, which is typically tiny - perhaps a couple kB, much less than 32MB. But it's still just one sort, and some opclasses may be much larger (like bloom, for example). So I just went with it. But for GIN it's more complicated, because we have two tuplesorts (not sure if both can use the memory at the same time) and the GIN deform buffer. Which probably means we need to have a per-worker allowance considering all these buffers. >> The trouble with (2) is that it "just copies" data from one tuplesort >> into another, increasing the disk space requirements. In an extreme >> case, when nothing can be combined, it pretty much doubles the amount of >> disk space, and makes the build longer. >> >> What I think Matthias is suggesting, is that this "TID list merging" >> could be done directly as part of the tuplesort in step (1). So instead >> of just moving the "sort tuples" from the appropriate runs, it could >> also do an optional step of combining the tuples and writing this >> combined tuple into the tuplesort result (for that worker). > > Yes, but with a slightly more extensive approach than that even, see above. > >> Matthias also mentioned this might be useful when building btree indexes >> with key deduplication. >> >> AFAICS this might work, although it probably requires for the "combined" >> tuple to be smaller than the sum of the combined tuples (in order to fit >> into the space). > > *must not be larger than the sum; not "must be smaller than the sum" [^0]. Yeah, I wrote that wrong. > For btree tuples with posting lists this is guaranteed to be true: The > added size of a btree tuple with a posting list (containing at least 2 > values) vs one without is the maxaligned size of 2 TIDs, or 16 bytes > (12 on 32-bit systems). The smallest btree tuple with data is also 16 > bytes (or 12 bytes on 32-bit systems), so this works out nicely. > >> But at least in the GIN build in the workers this is >> likely true, because the TID lists do not overlap (and thus not hurting >> the compressibility). >> >> That being said, I still see this more as an optimization than something >> required for the patch, > > Agreed. > OK >> and I don't think I'll have time to work on this >> anytime soon. The patch is not extremely complex, but it's not trivial >> either. But if someone wants to take a stab at extending tuplesort to >> allow this, I won't object ... > > Same here: While I do have some ideas on where and how to implement > this, I'm not planning on working on that soon. > Understood. I don't have a very good intuition on how significant the benefit could be, which is one of the reasons why I have not prioritized this very much. I did a quick experiment, to measure how expensive it is to build the second worker tuplesort - for the pg_trgm index build with 2 workers, it takes ~30seconds. The index build takes ~550s in total, so 30s is ~5%. If we eliminated all of this work we'd save this, but in reality some of it will still be necessary. Perhaps it's more significant for other indexes / slower storage, but it does not seem like a *must have* for v1. regards -- Tomas Vondra EnterpriseDB: http://www.enterprisedb.com The Enterprise PostgreSQL Company