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.96) (envelope-from ) id 1vsSkf-002JHy-0M for pgsql-hackers@arkaria.postgresql.org; Tue, 17 Feb 2026 21:37:01 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.96) (envelope-from ) id 1vsSke-00CTEk-0w for pgsql-hackers@arkaria.postgresql.org; Tue, 17 Feb 2026 21:37:00 +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.96) (envelope-from ) id 1vsSkd-00CTEX-35 for pgsql-hackers@lists.postgresql.org; Tue, 17 Feb 2026 21:37:00 +0000 Received: from relay4-d.mail.gandi.net ([217.70.183.196]) by magus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.98.2) (envelope-from ) id 1vsSkb-00000001GC9-3cPU for pgsql-hackers@lists.postgresql.org; Tue, 17 Feb 2026 21:36:59 +0000 Received: by mail.gandi.net (Postfix) with ESMTPSA id B99BA3EB69; Tue, 17 Feb 2026 21:36:54 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=vondra.me; s=gm1; t=1771364216; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=EtgXTJvcKcQya4jTILNMZutki0zOPlCBtRNX9f1ZLpY=; b=Av7o9LHezafU0Q/SxPFFLRvjH/UkNrqwqNLbYLUT9KLnUKimpXZg4nR+hJQCDD5mP51qqS A6yJJWOV+yWWmaKgm83KbFL/TCx6U9XGJgWvr2msmzEfsDLJG8xo4CxA7od3eLLfUi+S3I hUM91Clbw9Fqz+yuKc+GzuIgIYBgJHZp3eZZClQ7Xn/sOuI9U4N2UG/RfLlo18lT87OcX3 ePw0D+UBueKVE0aapt/AcSbrLExtDp2ny2UzDsb6D0Jpe7kIfHS1gyDUlLhn5F0CQBGPSC JP3rGsB8wlzYY/R6NRXnUFU2prU0AvVfrIkuhOY417azBdQ0lvju3+AZVl4ocA== Message-ID: <720560ca-97b9-40a1-ad40-9f9b8a6648e9@vondra.me> Date: Tue, 17 Feb 2026 22:36:53 +0100 MIME-Version: 1.0 User-Agent: Mozilla Thunderbird Subject: Re: index prefetching To: Peter Geoghegan , Andres Freund Cc: Alexandre Felipe , Thomas Munro , Nazir Bilal Yavuz , Robert Haas , Melanie Plageman , PostgreSQL Hackers , Georgios , Konstantin Knizhnik , Dilip Kumar References: <64a2re223ajj4popowsyu4xekbuvvyfwkrihn5yzyrkwsmsuvp@2lls3tpww5dl> <52512325-b1f2-4fff-819e-f68122b2e427@vondra.me> <64mfcfv7iihc4pmqlxarii4esnmqry52ckz5m7lmwylnfnuxuz@oxh4ioxkjtep> Content-Language: en-US From: Tomas Vondra In-Reply-To: Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-GND-Sasl: tomas@vondra.me X-GND-Score: -100 X-GND-Cause: gggruggvucftvghtrhhoucdtuddrgeefgedrtddtgddvvddtkeeiucetufdoteggodetrfdotffvucfrrhhofhhilhgvmecuifetpfffkfdpucggtfgfnhhsuhgsshgtrhhisggvnecuuegrihhlohhuthemuceftddunecusecvtfgvtghiphhivghnthhsucdlqddutddtmdenucfjughrpefkffggfgfuvfevfhfhjggtgfesthekredttddvjeenucfhrhhomhepvfhomhgrshcugghonhgurhgruceothhomhgrshesvhhonhgurhgrrdhmvgeqnecuggftrfgrthhtvghrnhepuedvvdeifefffeekudeggfdtieeglefggeduheffveeihefggfehgfdvudetffevnecukfhppeekiedrgeelrddvfedtrddvtdeinecuvehluhhsthgvrhfuihiivgeptdenucfrrghrrghmpehinhgvthepkeeirdegledrvdeftddrvddtiedphhgvlhhopegluddtrddufeejrddtrddvngdpmhgrihhlfhhrohhmpehtohhmrghssehvohhnughrrgdrmhgvpdhqihgupeeuleelueetfefgueeiledpmhhouggvpehsmhhtphhouhhtpdhnsggprhgtphhtthhopeduuddprhgtphhtthhopehpghessghofihtrdhivgdprhgtphhtthhopegrnhgurhgvshesrghnrghrrgiivghlrdguvgdprhgtphhtthhopehorghlvgigrghnughrvghfvghlihhpvgesghhmrghilhdrtghomhdprhgtphhtthhopehthhhomhgrshhmuhhnrhhosehgmhgrihhlrdgtohhmpdhrtghpthhtohepsgihrghvuhiikedusehgmhgrihhlrdgtohhmpdhrtghpthhto heprhhosggvrhhtmhhhrggrshesghhmrghilhdrtghomh X-GND-State: clean List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk On 2/17/26 21:16, Peter Geoghegan wrote: > On Tue, Feb 17, 2026 at 2:27 PM Andres Freund wrote: >> On 2026-02-17 12:16:23 -0500, Peter Geoghegan wrote: >>> On Mon, Feb 16, 2026 at 11:48 AM Andres Freund wrote: >>> I agree that the current heuristics (which were invented recently) are >>> too conservative. I overfit the heuristics to my current set of >>> adversarial queries, as a stopgap measure. >> >> Are you doing any testing on higher latency storage? I found it to be quite >> valuable to use dm_delay to have a disk with reproducible (i.e. not cloud) >> higher latency (i.e. not just a local SSD). > > I sometimes use dm_delay (with the minimum 1ms delay) when testing, > but don't do so regularly. Just because it's inconvenient to do so > (perhaps not a great reason). > >> Low latency NVMe can reduce the >> penalty of not enough readahead so much that it's hard to spot problems... > > I'll keep that in mind. > So, what counts as "higher latency" in this context? What delays should we consider practical/relevant for testing? >>> ISTM that we need the yields to better cooperate with whatever's >>> happening on the read stream side. >> >> Plausible. It could be that we could get away with controlling the rampup to >> be slower in potentially problematic cases, without needing the yielding, but >> not sure. >> >> If that doesn't work, it might just be sufficient to increase the number of >> batches that trigger yields as the scan goes on (perhaps by taking the number >> of already "consumed" batches into account). > > It could make sense to take the number of consumed batches into > account. In general, I think the best approach will be one that > combines multiple complementary strategies. > Yes, this is roughly what I meant by "ramp up". Start by limiting the batch distance to 2, then gradually increase that during the scan. > Passing down a LIMIT N hint has proven to be a good idea -- and it > doesn't really require applying any information related to the read > stream. That's enough to prevent problems in the really extreme cases > (e.g., nested loop antijoins with a LIMIT 1 on the inner side). The > problematic merge join I showed you is a not-so-extreme case, which > makes it trickier. ISTM that taking into consideration the number of > "consumed" batches will not help that particular merge join query, > precisely because it's not-so-extreme: the inner index scan consumes > plenty of batches, but is nevertheless significantly regressed (at > least when we don't yield at all). > >> To evaluate the amount of wasted work, it could be useful to make the read >> stream stats page spit out the amount of "unconsumed" IOs at the end of the >> scan. > > That would make sense. You can already tell when that's happened by > comparing the details shown by EXPLAIN ANALYZE against the same query > execution on master, but that approach is inconvenient. Automating my > microbenchmarks has proven to be important with this project. There's > quite a few competing considerations, and it's too easy to improve one > query at the cost of regressing another. > What counts as "unconsumed IO"? The IOs the stream already started, but then did not consume? That shouldn't be hard, I think. regards -- Tomas Vondra