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 1pVDQk-0007SO-Ln for pgsql-hackers@arkaria.postgresql.org; Thu, 23 Feb 2023 15:22:46 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.92) (envelope-from ) id 1pVDQh-0006mu-JS for pgsql-hackers@arkaria.postgresql.org; Thu, 23 Feb 2023 15:22:43 +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 1pVDQh-0006ml-5v for pgsql-hackers@lists.postgresql.org; Thu, 23 Feb 2023 15:22:43 +0000 Received: from mail-ed1-x533.google.com ([2a00:1450:4864:20::533]) by makus.postgresql.org with esmtps (TLS1.3:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.92) (envelope-from ) id 1pVDQe-0007aN-JB for pgsql-hackers@lists.postgresql.org; Thu, 23 Feb 2023 15:22:42 +0000 Received: by mail-ed1-x533.google.com with SMTP id ck15so44644034edb.0 for ; Thu, 23 Feb 2023 07:22:40 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=enterprisedb.com; s=google; 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=aHMvo0yd/IdnSIIDQb2h7vniFeH4jt/dA3OIzCV8MJA=; b=ZsjdeFipzbhw51SZYaDJ8CxcASgvJUaT9h83Ah2lKzdcHBnKJrSoV/cebYMyHK9vYo WVK1mEpJLNTiIFEWJlgPbUVtPXk/nYdVOYP+78VhaAWCpnN7vNETq4ifFCO3Bw/5uHwQ Wvbv2eaI3EhIQXjMQzU3bgb0heHAInagkEwQTKlb7kBuQtJqQoO7mOSyCSEBaXl5z5Cz 9Uc3Pv1YEJc4pN2X/iQcaSpJ7Wm8gWt1K88uJ7o3YWvlyHzkF9aePgBW6FpfPJehZfbW s14cKGL5MqXuJ3Xzic4hW8LmNQHu9RxZWyu90V0PhaEb05VY4/rnwOOpu3RLyVkOFHVk Eaww== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; 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=aHMvo0yd/IdnSIIDQb2h7vniFeH4jt/dA3OIzCV8MJA=; b=h6hRHe13xCVS7yJx8psbHddvWULcogMgX0inUH8jIL3bOFCQoGm7Y+eHK8q9PnAOLw Q/7sj0b4m0YR5JRv33xsKjIMQHM93SfVJrTWLsmzI1klJj8C544jfqv02uMSLGrtMvpb BUN/XczsVcsRERfbKmZgh/W/C/zwvoZeTbwwSePgpkKG43i0wVSXeEJtGuymFK5tqeOf rU1g8LIMpOT6F28q4FKO0Y19BEqNTDUVQ1JJWGSO1iF9zbkVQE4MYdKwq6IoW1NE0a4L XPgsewAnXWRmCic06NSx0sjl1scXwc3qhrlqfdZzW+4iJ1Hdc+LEV/EARpcCQIuQAytB 7zJQ== X-Gm-Message-State: AO0yUKU5YDELfGEIU7O/wuQIiiRJnwaDp0F0qg9hS2iaHEYct8t1onZQ pv5mhwcg33bApDlDBQQkkUOoPhSW9V1HhXZnXo/LXIhv6bj+9hyaKOHxvCKNSCmFPyLTMD0Wa8U R8KFic8fNZBUOf/oY9MIl0MpwvDiXveobFR3OhFzEOcY7dCj6Dg+x9dbdezUrV3NPnAgLtnrjwq 50dl/AXJIwhNV90DoVxrEFOs2SH9ynjX1+IRp2d43m7wJIB9vrW98j X-Google-Smtp-Source: AK7set+aBRFUlS2PR/b51Fzm0DNtvO5GhW6ZWU/Lie9oQeX6s44si+FwapkMb+iDkaeALz+TWGICpg== X-Received: by 2002:a17:906:c7c6:b0:8af:305b:76af with SMTP id dc6-20020a170906c7c600b008af305b76afmr19874745ejb.33.1677165758977; Thu, 23 Feb 2023 07:22:38 -0800 (PST) Received: from [10.137.0.17] (static-84-42-175-93.bb.vodafone.cz. [84.42.175.93]) by smtp.gmail.com with ESMTPSA id g16-20020a170906595000b008dd3956c2e3sm3847718ejr.183.2023.02.23.07.22.38 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Thu, 23 Feb 2023 07:22:38 -0800 (PST) Message-ID: <30f37aae-57fa-e7ab-9444-7b82969ed68f@enterprisedb.com> Date: Thu, 23 Feb 2023 16:22:37 +0100 MIME-Version: 1.0 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:102.0) Gecko/20100101 Thunderbird/102.8.0 Subject: Re: PATCH: Using BRIN indexes for sorted output To: Matthias van de Meent Cc: Justin Pryzby , Andres Freund , Greg Stark , Zhihong Yu , PostgreSQL Hackers References: <1607e037-8c5b-1626-9f98-496f067b9eb5@enterprisedb.com> <0695af03-8bd3-f032-47aa-0657135ce45d@enterprisedb.com> <87964cda-e440-8759-2838-bc4628072a18@enterprisedb.com> <14568731-ac91-ce2d-1477-0e2504c72775@enterprisedb.com> <20221206185143.ivy3afwmkhloksgv@awork3.anarazel.de> <4e679562-fd9a-33a3-ce71-cd7a27525f8e@enterprisedb.com> <20230216161016.GV1653@telsasoft.com> <9f73f798-1dac-c75d-d834-aa012ba13b65@enterprisedb.com> <8f1374d1-6f4b-ce99-84eb-ffa852c0dadb@enterprisedb.com> Content-Language: en-US From: Tomas Vondra In-Reply-To: Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 7bit X-CLOUD-SEC-AV-Info: enterprisedb,google_mail,monitor X-CLOUD-SEC-AV-Sent: true X-Gm-Spam: 0 X-Gm-Phishy: 0 List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk On 2/23/23 15:19, Matthias van de Meent wrote: > On Sat, 18 Feb 2023 at 16:55, Tomas Vondra > wrote: >> >> cfbot complained there's one more place triggering a compiler warning on >> 32-bit systems, so here's a version fixing that. >> >> I've also added a copy of the regression tests but using the indexam >> stats added in 0001. This is just a copy of the already existing >> regression tests, just with enable_indexam_stats=true - this should >> catch some of the issues that went mostly undetected in the earlier >> patch versions. > > > Comments on 0001, mostly comments and patch design: > >> +range_minval_cmp(const void *a, const void *b, void *arg) >> [...] >> +range_maxval_cmp(const void *a, const void *b, void *arg) >> [...] >> +range_values_cmp(const void *a, const void *b, void *arg) > > Can the arguments of these functions be modified into the types they > are expected to receive? If not, could you add a comment on why that's > not possible? > I don't think it's good practise to "just" use void* for arguments to > cast them to more concrete types in the next lines without an > immediate explanation. > The reason is that that's what qsort() expects. If you change that to actual data types, you'll get compile-time warnings. I agree this may need better comments, though. >> + * Statistics calculated by index AM (e.g. BRIN for ranges, etc.). > > Could you please expand on this? We do have GIST support for ranges, too. > Expand in what way? This is meant to be AM-specific, so if GiST wants to collect some additional stats, it's free to do so - perhaps some of the ideas from the stats collected for BRIN would be applicable, but it's also bound to the index structure. >> + * brin_minmax_stats >> + * Calculate custom statistics for a BRIN minmax index. >> + * >> + * At the moment this calculates: >> + * >> + * - number of summarized/not-summarized and all/has nulls ranges > > I think statistics gathering of an index should be done at the AM > level, not attribute level. The docs currently suggest that the user > builds one BRIN index with 16 columns instead of 16 BRIN indexes with > one column each, which would make the statistics gathering use 16x > more IO if the scanned data cannot be reused. > Why? The row sample is collected only once and used for building all the index AM stats - it doesn't really matter if we analyze 16 single-column indexes or 1 index with 16 columns. Yes, we'll need to scan more indexes, but the with 16 columns the summaries will be larger so the total amount of I/O will be almost the same I think. Or maybe I don't understand what I/O you're talking about? > It is possible to build BRIN indexes on more than one column with more > than one opclass family like `USING brin (id int8_minmax_ops, id > int8_bloom_ops)`. This would mean various duplicate statistics fields, > no? > It seems to me that it's more useful to do the null- and n_summarized > on the index level instead of duplicating that inside the opclass. I don't think it's worth it. The amount of data this would save is tiny, and it'd only apply to cases where the index includes the same attribute multiple times, and that's pretty rare I think. I don't think it's worth the extra complexity. > >> + for (heapBlk = 0; heapBlk < nblocks; heapBlk += pagesPerRange) > > I am not familiar with the frequency of max-sized relations, but this > would go into an infinite loop for pagesPerRange values >1 for > max-sized relations due to BlockNumber wraparound. I think there > should be some additional overflow checks here. > Good point, but that's a pre-existing issue. We do this same loop in a number of places. >> +/* >> + * get_attstaindexam >> + * >> + * Given the table and attribute number of a column, get the index AM >> + * statistics. Return NULL if no data available. >> + * > > Shouldn't this be "given the index and attribute number" instead of > "the table and attribute number"? > I think we need to be compatible with indexes on expression here, so > that we don't fail to create (or use) statistics for an index `USING > brin ( (int8range(my_min_column, my_max_column, '[]')) > range_inclusion_ops)` when we implement stats for range_inclusion_ops. > >> + * Alternative to brin_minmax_match_tuples_to_ranges2, leveraging ordering > > Does this function still exist? > Yes, but only in 0003 - it's a "brute-force" algorithm used as a cross-check the result of the optimized algorithm in 0001. You're right it should not be referenced in the comment. > > I'm planning on reviewing the other patches, and noticed that a lot of > the patches are marked WIP. Could you share a status on those, because > currently that status is unknown: Are these patches you don't plan on > including, or are these patches only (or mostly) included for > debugging? > I think the WIP label is a bit misleading, I used it mostly to mark patches that are not meant to be committed on their own. A quick overview: 0002-wip-introduce-debug_brin_stats-20230218-2.patch 0003-wip-introduce-debug_brin_cross_check-20230218-2.patch Not meant for commit, used mostly during development/debugging, by adding debug logging and/or cross-check to validate the results. I think it's fine to ignore those during review. 0005-wip-brinsort-explain-stats-20230218-2.patch This needs more work. It does what it's meant to do (show info about the brinsort node), but I'm not very happy with the formatting etc. Review and suggestions welcome. 0006-wip-multiple-watermark-steps-20230218-2.patch 0007-wip-adjust-watermark-step-20230218-2.patch 0008-wip-adaptive-watermark-step-20230218-2.patch Ultimately this should be merged into 0004 (which does the actual brinsort), I think 0006 is the way to go, but I kept all the patches to show the incremental evolution (and allow comparisons). 0006 adds a GUC to specify how many ranges to add in each round, 0005 adjusts that based on statistics during planning and 0006 does that adaptively during execution. 0009-wip-add-brinsort-regression-tests-20230218-2.patch 0010-wip-add-brinsort-amstats-regression-tests-20230218-2.patch These need to move to the earlier parts. The tests are rather expensive so we'll need to reduce it somehow. 0011-wip-test-generator-script-20230218-2.patch Not intended for commit, I only included it to keep it as part of the patch series. regards -- Tomas Vondra EnterpriseDB: http://www.enterprisedb.com The Enterprise PostgreSQL Company