Received: from malur.postgresql.org ([217.196.149.56]) by arkaria.postgresql.org with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1pVeok-0003yX-Oy for pgsql-performance@arkaria.postgresql.org; Fri, 24 Feb 2023 20:37:22 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.92) (envelope-from ) id 1pVeoj-0000g8-Hy for pgsql-performance@arkaria.postgresql.org; Fri, 24 Feb 2023 20:37:21 +0000 Received: from makus.postgresql.org ([2001:4800:3e1:1::229]) by malur.postgresql.org with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1pVeoj-0000fz-34 for pgsql-performance@lists.postgresql.org; Fri, 24 Feb 2023 20:37:21 +0000 Received: from mail-il1-x134.google.com ([2607:f8b0:4864:20::134]) by makus.postgresql.org with esmtps (TLS1.3:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.92) (envelope-from ) id 1pVeog-0006Ba-21 for pgsql-performance@postgresql.org; Fri, 24 Feb 2023 20:37:19 +0000 Received: by mail-il1-x134.google.com with SMTP id z5so520710ilq.0 for ; Fri, 24 Feb 2023 12:37:17 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=telsasoft-com.20210112.gappssmtp.com; s=20210112; h=user-agent:in-reply-to:content-transfer-encoding :content-disposition:mime-version:references:message-id:subject:cc :to:from:date:from:to:cc:subject:date:message-id:reply-to; bh=phe6ztVJ9kIjxzzsHcbhGaDExtUGK5+CLby99cT2xVg=; b=UCI8UhzupUEVdB3roOd6GdMZfw3P1gwDOSu93ydqnlJ2AP16pFg9CEZYfgMdW9G9A1 mRhEAFqO7KYdwOfRycMR/YqfXDqbo98BetzF24g/yG0pEW0R3jlmhkVVdllvgzBbJzzf WKCDK0weOxK22KBa0yhP7jU2JvTlaId/7fyNAnKuC4JeI257cgkjBxCBM7YuErBFnHEy Q6p1iZsywk7TZfO1WBjtgyQUBcoUPGt7K95wmCyIfCueYoLyjtBAyXUjv45gygXQrsuT ZsCwR8mR01R6u4kTMLIkjpj7xJ9BzDEM6BuhOMmKiWZP8k287VTFTV1DVTHKqOiE85yd brOQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=user-agent:in-reply-to:content-transfer-encoding :content-disposition:mime-version:references:message-id:subject:cc :to:from:date:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=phe6ztVJ9kIjxzzsHcbhGaDExtUGK5+CLby99cT2xVg=; b=QJ1yQsE5CcGbmI7IoJ11sUhjCO9isRUzlPYJf0c0iXUylXLF0ZENVsJiccur/ZySjo ocCy4d1Qp6i4BLDA+WMUV65gk8NDQSqqRjqeM/OVKvWK9teCdmr/byLjLYsMJpgfHxsW NKX+K6xOCo7We0LwUe3J+O3T35/ugvmtLiWNxSc7L7R4cAzoay4iI/g73jZKdx3ho4fL ceTnmqZOlqnqWlFaqgT9yRF1ZwXfr1nUTWB6ARXrDV7mkjD7mPuahzL7Xl2eZxta/8Qs m+5jl0v8q5Uo8G+/bwdN0L7CT0NxiGPvPXSkihbqCsMYAxHvjcRQiPXh4Hw0mwfUmiYq rsbg== X-Gm-Message-State: AO0yUKXRuinCI4BM1KMGoKnm/wB7syqakOgxeAEqdyqkvDU/36W0ORKk nBshowdOFdE5Pcn3f0Ezo66jcw== X-Google-Smtp-Source: AK7set969J+QqMCYiK3meHLvhKAYYErcsAEeu6+/6pysgUEs9pJZ2DxuuvFdjQrRaOILjArT238Vig== X-Received: by 2002:a92:ca09:0:b0:315:365d:534f with SMTP id j9-20020a92ca09000000b00315365d534fmr17827514ils.19.1677271037223; Fri, 24 Feb 2023 12:37:17 -0800 (PST) Received: from pryzbyj.telsasoft (charmander.telsasoft.com. [50.244.222.1]) by smtp.gmail.com with ESMTPSA id z15-20020a92da0f000000b003152eec4057sm38543ilm.27.2023.02.24.12.37.16 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 24 Feb 2023 12:37:16 -0800 (PST) Received: by pryzbyj.telsasoft (Postfix, from userid 1000) id 947D1800BF2; Fri, 24 Feb 2023 14:37:15 -0600 (CST) Date: Fri, 24 Feb 2023 14:37:15 -0600 From: Justin Pryzby To: Mickael van der Beek Cc: pgsql-performance@postgresql.org Subject: Re: BRIN index worse than sequential scan for large search set Message-ID: <20230224203715.GE1653@telsasoft.com> References: <20230224171944.GB1653@telsasoft.com> MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Disposition: inline Content-Transfer-Encoding: 8bit In-Reply-To: User-Agent: Mutt/1.9.4 (2018-02-28) List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk On Fri, Feb 24, 2023 at 06:51:00PM +0100, Mickael van der Beek wrote: > Hello Justin, > > Thanks for the quick response! > > > The table may be dense, but the tuples aren't. You're asking to return > > 1/1000th of the tuples, across the entire table. Suppose there are ~100 > > tuples per page, and you need to read about every 10th page. It makes > > sense that it's slow to read a large amount of data nonsequentially. > > Ah, of course, you're right! > I forgot that the BRIN indexes store ranges that are not fully covered by > the row values and that PostgreSQL has to double-check (bitmap heap scan) > ... > Would you thus advise to only use BRIN indexes for columns who's values are > (1) monotonically increasing but also (2) close to each other? It's not important whether they're "rigidly" monotonic (nor "strictly"). What's important is that a query doesn't need to access a large number of pages. For example, some of the BRIN indexes that I'm familiar with are created on a column called "start time", but the table's data tends to be naturally sorted by "end time" - and that's good enough. If someone queries for data between 12pm and 1pm, there's surely no data for the first 12 hours of the day's table (because it hadn't happened yet) and there's probably no data for the last 9+ hours of the day, either, so it's only got to read data for a 1-2h interval in the middle. This assumes that the column's data is typically correlated. If the tuples aren't clustered/"close to each other" then it probably doesn't work well. I haven't played with brin "multi minmax", though. > > > 2. Since we only select the "idx" column, why does the BRIN index not > > > simply return the searched value if included in one of it's ranges? > > > Hitting the actual row data stored in the table seems to be unnessary no? > > > > Because it's necessary to check if the tuple is visible to the current > > transaction. It might be from an uncommited/aborted transaction. Actually, a better explanation is that all the brin scan returns is the page, and not the tuples. "BRIN indexes can satisfy queries via regular bitmap index scans, and will return all tuples in all pages within each range if the summary info stored by the index is CONSISTENT with the query conditions. The query executor is in charge of rechecking these tuples and discarding those that do not match the query conditions — in other words, these indexes are LOSSY". The index is returning pages where matching tuples *might* be found, after excluding those pages where it's certain that no tuples are found. -- Justin