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 1rAQ5d-006e6S-GZ for pgsql-hackers@arkaria.postgresql.org; Tue, 05 Dec 2023 07:43:33 +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 1rAQ5a-002d6s-44 for pgsql-hackers@arkaria.postgresql.org; Tue, 05 Dec 2023 07:43:30 +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 1rAQ5Z-002d6k-MN for pgsql-hackers@lists.postgresql.org; Tue, 05 Dec 2023 07:43:29 +0000 Received: from lahtoruutu.iki.fi ([2a0b:5c81:1c1::37]) by magus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.94.2) (envelope-from ) id 1rAQ5X-00ABIB-2h for pgsql-hackers@postgresql.org; Tue, 05 Dec 2023 07:43:28 +0000 Received: from [192.168.1.115] (dsl-hkibng22-54f8db-125.dhcp.inet.fi [84.248.219.125]) (using TLSv1.3 with cipher TLS_AES_128_GCM_SHA256 (128/128 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) (Authenticated sender: hlinnaka) by lahtoruutu.iki.fi (Postfix) with ESMTPSA id 4SkswD0WLDz49Q3J; Tue, 5 Dec 2023 09:43:21 +0200 (EET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=iki.fi; s=lahtoruutu; t=1701762204; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=7/yELuxiPCXOOSCam/kkhhLdA7FwQPLT4p3Ldfe+toU=; b=cs66y7gDQo3D6+/reBgVpvSwu3R4x0ZwgPyRsNkpdx7aboYRGfBtgBXrcRrLMjL1B8p57t eH18WwLui5ttORFitE7Ylnvpzp641UDX85LY2ukZLMwAE4vNaD4HZiBsb9jebiQHTGPoSk dIDS0A3bg6F8G/KFF58o/RljiI85BaqqumbJgDNLLClFjJiNfohxDQyEV1V1BgEypzz3Gr 3WiVIMp96b+I3oFOy8H2pS6bQPlo1xmOGH3zb3KJ7z/iEmHFVr2EMs9F1w/pea+WquZN8g K4S1fwSMicJTcygo6lzNjNeeh1JiRIRWX+EnJwZBDD3i+BqaxcaIsCWcWcdQaw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=iki.fi; s=lahtoruutu; t=1701762204; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=7/yELuxiPCXOOSCam/kkhhLdA7FwQPLT4p3Ldfe+toU=; b=PJGgonNmC1kZUWsIbBd2BsvDIrPx8nX4W3iCaGzGos935KmE2ot+HuULt3iWxz/QDpvU/K U1L6sR60fOKLvASa4YvRazJ+lY2d4jE0qgVmLpYGdpV0fxcjLN8acmWZImV/sK5zNdyowb 7GYtaMkuUpeD065Jlm+oFC3LuV/llXFtc5vrcBlh1POfVq7hhwEgi9p649X6tA41070Yvm f/AEiXew7M6S0FP9kbVwIi36Vx/Q3dTO8nFz05Em/NhEcz5UwL0b9d6Nw3DhD8Z1SVqvP6 QvUtvo1NJ1L/7H5bmj3eG/nUKo9qfVJpquH7jLRGFrLf9FYmSIBfGHNvkqYE9w== ARC-Seal: i=1; s=lahtoruutu; d=iki.fi; t=1701762204; a=rsa-sha256; cv=none; b=vB2StYo4ncB7ijx0q/dhka05Cb0mU6qtv9vtvbLuksG+e8F9EK5W0ys/8LGtL1c1g1I7+L g2RXkICUsw1VAL5VlQOtk5doX233AH5yTb5VQg2V4O2njptIsEdOcjR9rlDgx6LGdnvgaU qC1ac+lzgaIbJfSieD58AP6mIjtIF5MX8ZpKJTzvszrfD087RmHaPe/05qLo7/21yDZCz4 92CD8VCWJGB+ZJFjdrYb9DtrdmtXljFXtoBVVxcLSdS1QnSDtgIwx23foR5R5ydwOcwexS NF6o7DgaWNIAkhHKlEz0oEeYU+oXbqXKV4p/LTWO4t62T58DAD4n4FH4qAhm7w== ARC-Authentication-Results: i=1; ORIGINATING; auth=pass smtp.auth=hlinnaka smtp.mailfrom=hlinnaka@iki.fi Message-ID: Date: Tue, 5 Dec 2023 09:43:20 +0200 MIME-Version: 1.0 User-Agent: Mozilla Thunderbird Subject: Re: btree: downlink right separator/HIKEY optimization Content-Language: en-US To: Matthias van de Meent , PostgreSQL Hackers , Peter Geoghegan , Dilip Kumar , David Christensen References: From: Heikki Linnakangas In-Reply-To: Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 7bit List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk On 01/11/2023 00:08, Matthias van de Meent wrote: > calling _bt_compare in _bt_moveright in many common cases. This patch, > when stacked on top of the prefix truncation patch, improves INSERT > performance by an additional 2-9%pt, with an extreme case of 45% in > the worscase index tests at [0]. > > The optimization is that we now recognze that our page split algorithm > all but guarantees that the HIKEY matches this page's downlink's right > separator key bytewise, excluding the data stored in the > IndexTupleData struct. Good observation. > By caching the right separator index tuple in _bt_search, we can > compare the downlink's right separator and the HIKEY, and when they > are equal (memcmp() == 0) we don't have to call _bt_compare - the > HIKEY is known to be larger than the scan key, because our key is > smaller than the right separator, and thus transitively also smaller > than the HIKEY because it contains the same data. As _bt_compare can > call expensive user-provided functions, this can be a large > performance boon, especially when there are only a small number of > column getting compared on each page (e.g. index tuples of many 100s > of bytes, or dynamic prefix truncation is enabled). What would be the worst case scenario for this? One situation where the memcmp() would not match is when there is a concurrent page split. I think it's OK to pessimize that case. Are there any other situations? When the memcmp() matches, I think this is almost certainly not slower than calling the datatype's comparison function. > if (offnum < PageGetMaxOffsetNumber(page)) > { > ItemId rightsepitem = PageGetItemId(page, offnum + 1); > IndexTuple pagerightsep = (IndexTuple) PageGetItem(page, rightsepitem); > memcpy(rsepbuf.data, pagerightsep, ItemIdGetLength(rightsepitem)); > rightsep = &rsepbuf.tuple; > } > else if (!P_RIGHTMOST(opaque)) > { > /* > * The rightmost data tuple on inner page has P_HIKEY as its right > * separator. > */ > ItemId rightsepitem = PageGetItemId(page, P_HIKEY); > IndexTuple pagerightsep = (IndexTuple) PageGetItem(page, rightsepitem); > memcpy(rsepbuf.data, pagerightsep, ItemIdGetLength(rightsepitem)); > rightsep = &rsepbuf.tuple; > } This could use a one-line comment above this, something like "Remember the right separator of the downlink we follow, to speed up the next _bt_moveright call". Should there be an "else rightsep = NULL;" here? Is it possible that we follow the non-rightmost downlink on a higher level and rightmost downlink on next level? Concurrent page deletion? Please update the comment above _bt_moveright to describe the new argument. Perhaps the text from README should go there, this feels like a detail specific to _bt_search and _bt_moveright. -- Heikki Linnakangas Neon (https://neon.tech)