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 1rcmqu-0024Q4-SW for pgsql-hackers@arkaria.postgresql.org; Wed, 21 Feb 2024 13:41:37 +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 1rcmqr-004d1X-1g for pgsql-hackers@arkaria.postgresql.org; Wed, 21 Feb 2024 13:41:33 +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 1rcmqq-004d1P-Oh for pgsql-hackers@lists.postgresql.org; Wed, 21 Feb 2024 13:41:33 +0000 Received: from m16.mail.163.com ([117.135.210.3]) by magus.postgresql.org with esmtp (Exim 4.94.2) (envelope-from ) id 1rcmqf-000B55-Bh for pgsql-hackers@lists.postgresql.org; Wed, 21 Feb 2024 13:41:31 +0000 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=163.com; s=s110527; h=From:Subject:Date:Message-ID:MIME-Version: Content-Type; bh=131ajtL4f0i+4KRsq3RAMFz5Iyi9dyCx0uU1RKOZMZg=; b=QLqLaroGmbPiF5X+7lcsglEV6gehqr0QTcb3GPykpr03eZLagyCbN4M3Zox7Cd inAyvlyHkGBp/INuPdpxVWSoXkkqYL2+GZAyzHbHBtbb6gEMsvtIfaWB0m0UJTxm 7wFTAf9OA2lo+uns0DejEtRBE1JD+vs/5daoKwON/9rD0= Received: from 8235eee8a2a0 (unknown [140.205.118.217]) by gzga-smtp-mta-g1-5 (Coremail) with SMTP id _____wBXT0tr_dVlmmpDDg--.38159S3; Wed, 21 Feb 2024 21:40:59 +0800 (CST) References: <87il4jrk1l.fsf@163.com> <87h6jxw41k.fsf@163.com> <87sf3andy2.fsf@163.com> <87wmskm9qu.fsf@163.com> <87v87kvboq.fsf@163.com> <71321d83-391b-473b-aaf6-618c7f682b96@postgrespro.ru> <87r0i7vos3.fsf@163.com> <874je3hcwn.fsf@163.com> <8734tmg88e.fsf@163.com> <7f4c8673-4c5d-4dbf-b8e5-0ec11cd2fba0@enterprisedb.com> User-agent: mu4e 1.10.7; emacs 29.1 From: Andy Fan To: Tomas Vondra Cc: Michael Zhilin , Peter Smith , vignesh C , Matthias van de Meent , Nikita Malakhov , pgsql-hackers@lists.postgresql.org Subject: Re: Shared detoast Datum proposal Date: Wed, 21 Feb 2024 21:20:38 +0800 In-reply-to: <7f4c8673-4c5d-4dbf-b8e5-0ec11cd2fba0@enterprisedb.com> Message-ID: <87h6i2djf9.fsf@163.com> MIME-Version: 1.0 Content-Type: text/plain X-CM-TRANSID: _____wBXT0tr_dVlmmpDDg--.38159S3 X-Coremail-Antispam: 1Uf129KBjvJXoW3Jw4rur1DtF1xJr4fKry5CFg_yoW7Gw4Upr W3JayjgFs8Arn5tF9avw48JF1F9rZ3JF4Yyrn8J34j93y5XryIqr1Fg3y8AFZrCrWkXF4Y vw4UXr1rZa98AaDanT9S1TB71UUUUU7qnTZGkaVYY2UrUUUUjbIjqfuFe4nvWSU5nxnvy2 9KBjDUYxBIdaVFxhVjvjDU0xZFpf9x0zRpwZ3UUUUU= X-Originating-IP: [140.205.118.217] X-CM-SenderInfo: x2klx3xlid0iqsrtqiywtou0bp/xtbBzxCLU2V4H5QWsgAAs1 List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk I see your reply when I started to write a more high level document. Thanks for the step by step help! Tomas Vondra writes: > On 2/20/24 19:38, Andy Fan wrote: >> >> ... >> >>> I think it should be done the other >>> way around, i.e. the patch should introduce the main feature first >>> (using the traditional Bitmapset), and then add Bitset on top of that. >>> That way we could easily measure the impact and see if it's useful. >> >> Acutally v4 used the Bitmapset, and then both perf and pgbench's tps >> indicate it is too expensive. and after talk with David at [2], I >> introduced bitset and use it here. the test case I used comes from [1]. >> IRCC, there were 5% performance difference because of this. >> >> create table w(a int, b numeric); >> insert into w select i, i from generate_series(1, 1000000)i; >> select b from w where b > 0; >> >> To reproduce the difference, we can replace the bitset_clear() with >> >> bitset_free(slot->pre_detoasted_attrs); >> slot->pre_detoasted_attrs = bitset_init(slot->tts_tupleDescriptor->natts); >> >> in ExecFreePreDetoastDatum. then it works same as Bitmapset. >> > > I understand the bitset was not introduced until v5, after noticing the > bitmapset is not quite efficient. But I still think the patches should > be the other way around, i.e. the main feature first, then the bitset as > an optimization. > > That allows everyone to observe the improvement on their own (without > having to tweak the code), and it also doesn't require commit of the > bitset part before it gets actually used by anything. I start to think this is a better way rather than the opposite. The next version will be: 0001: shared detoast datum feature with high level introduction. 0002: introduce bitset and use it shared-detoast-datum feature, with the test case to show the improvement. >> I will do more test on the memory leak stuff, since there are so many >> operation aginst slot like ExecCopySlot etc, I don't know how to test it >> fully. the method in my mind now is use TPCH with 10GB data size, and >> monitor the query runtime memory usage. >> > > I think this is exactly the "high level design" description that should > be in a comment, somewhere. Got it. >>> Of course, expanded datums are >>> not meant to be long-lived, while "shared detoasted values" are meant to >>> exist (potentially) for the query duration. >> >> hmm, acutally the "shared detoast value" just live in the >> TupleTableSlot->tts_values[*], rather than the whole query duration. The >> simple case is: >> >> SELECT * FROM t WHERE a_text LIKE 'abc%'; >> >> when we scan to the next tuple, the detoast value for the previous tuple >> will be relased. >> > > But if the (detoasted) value is passed to the next executor node, it'll > be kept, right? Yes and only one copy for all the executor nodes. > Unrelated question - could this actually end up being too aggressive? > That is, could it detoast attributes that we end up not needing? For > example, what if the tuple gets eliminated for some reason (e.g. because > of a restriction on the table, or not having a match in a join)? Won't > we detoast the tuple only to throw it away? The detoast datum will have the exactly same lifespan with other tts_values[*]. If the tuple get eliminated for any reason, those detoast datum still exist until the slot is cleared for storing the next tuple. >> typedef struct Join >> { >> .. >> /* >> * Records of var's varattno - 1 where the Var is accessed indirectly by >> * any expression, like a > 3. However a IS [NOT] NULL is not included >> * since it doesn't access the tts_values[*] at all. >> * >> * This is a essential information to figure out which attrs should use >> * the pre-detoast-attrs logic. >> */ >> Bitmapset *outer_reference_attrs; >> Bitmapset *inner_reference_attrs; >> } Join; >> > > Is it actually necessary to add new fields to these nodes? Also, the > names are not particularly descriptive of the purpose - it'd be better > to have "detoast" in the name, instead of generic "reference". Because of the way of the data transformation, I think we must add the fields to keep such inforamtion. Then these information will be used initilize the necessary information in PlanState. maybe I am having a fixed mindset, I can't think out a way to avoid that right now. I used 'reference' rather than detoast is because some implementaion issues. In the createplan.c and setref.c, I can't check the atttyplen effectively, so even a Var with int type is still hold here which may have nothing with detoast. >> >> When I worked with the UniqueKey feature, I maintained a >> UniqueKey.README to summaried all the dicussed topics in threads, the >> README is designed to save the effort for more reviewer, I think I >> should apply the same logic for this feature. >> > > Good idea. Either that (a separate README), or a comment in a header of > some suitable .c/.h file (I prefer that, because that's kinda obvious > when reading the code, I often not notice a README exists next to it). Great, I'd try this from tomorrow. -- Best Regards Andy Fan