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 1kG4UK-0001IN-41 for pgsql-hackers@arkaria.postgresql.org; Wed, 09 Sep 2020 18:06:32 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.92) (envelope-from ) id 1kG4UJ-0003C9-2C for pgsql-hackers@arkaria.postgresql.org; Wed, 09 Sep 2020 18:06:31 +0000 Received: from magus.postgresql.org ([2a02:c0:301:0:ffff::29]) by malur.postgresql.org with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1kG4UI-0003C2-LC for pgsql-hackers@lists.postgresql.org; Wed, 09 Sep 2020 18:06:30 +0000 Received: from mail-ed1-x544.google.com ([2a00:1450:4864:20::544]) by magus.postgresql.org with esmtps (TLS1.3:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.92) (envelope-from ) id 1kG4UF-0001LC-JA for pgsql-hackers@postgresql.org; Wed, 09 Sep 2020 18:06:30 +0000 Received: by mail-ed1-x544.google.com with SMTP id c10so3613260edk.6 for ; Wed, 09 Sep 2020 11:06:27 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=2ndquadrant-com.20150623.gappssmtp.com; s=20150623; h=date:from:to:cc:subject:message-id:references:mime-version :content-disposition:in-reply-to; bh=tm+S8WItZaYkg4RRVgRji9F1U4LyKb2Mh821VHQMU5E=; b=y5CflFC8fNI16jR4XNzOzlrmSJz46+XabNTFDo50gIGuP35AJ6k82rI1cfu7PKGaUX Z/aWF6ynuokt0AnpUtwulNc7zo6ayLOv1VPi9DR8iN8lHcuONTsik5bMpcSrWkisqHuu 7PB8+X7YrtjGbqcgrb/JSKKP2ZD4sMHCJFQGWaMoHPYHRM9z4TiSvJyELx7m99axtq3T qZ6PpONFZwZgehZpna9AbOe0a46LKiCBQ1hyASZsbbEpkvahbybI09e/rl/X0Ny5kLIM Wkz50mjy+fPIYTA/EMUU8K3mPXsk3umpQydOw775cT+l4QC+s26RaaV78koLZxbs/xkU ECYA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:from:to:cc:subject:message-id:references :mime-version:content-disposition:in-reply-to; bh=tm+S8WItZaYkg4RRVgRji9F1U4LyKb2Mh821VHQMU5E=; b=kTDcfc5cLT2LYjKaFOitbHFIeAJXAWT7xJGIDd9C3LcUyc3YUic8F+WQt72t08fNy8 gRdYEzayYBGSDKK94BHg/IlwfQFjYBqPO7LQIJueF5AlNydVsDvK8IQEsyo0+BTlLoVJ yz3Iazl7Oyt31ap3e4i6AO5B6k8/siLhbywNQHNTXOerTCX5oJHQTCRDCEJF4qzEdIeL 6/OfACmP4utHB1OvMgirXMgCWUqoYL+XutrtHW6q+p07dZjWD1YZwWn1qlodpexEnh4x bL+j7z+gLZ6vnjJE8W+hLt3xpMd377Kg0JHXHZSUBYWPlFn/sRr8cTNaIRcS059iria8 pZXA== X-Gm-Message-State: AOAM530oVjKsyBcH3NHPQl+2E6w6sV0krTs+UdW6RCI7rWqTwG4P0qI6 sjLEHxKZt2dtjHHaS7l1iqoYRg== X-Google-Smtp-Source: ABdhPJwioQkB7wM+RlNykbgUQgkfjqk5V61se5QHfl3fLWnXxPP3iGOzRv6xUglzIHn7ZH1SgeJ1pQ== X-Received: by 2002:aa7:dad8:: with SMTP id x24mr5322359eds.19.1599674785606; Wed, 09 Sep 2020 11:06:25 -0700 (PDT) Received: from localhost (ip-86-49-253-216.net.upcbroadband.cz. [86.49.253.216]) by smtp.gmail.com with ESMTPSA id mb16sm3201286ejb.45.2020.09.09.11.06.21 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 09 Sep 2020 11:06:22 -0700 (PDT) Date: Wed, 9 Sep 2020 20:06:20 +0200 From: Tomas Vondra To: John Naylor Cc: pgsql-hackers Subject: Re: WIP: BRIN multi-range indexes Message-ID: <20200909180620.k7dso2cxhyxokxql@development> References: <20200713145850.5skhxmqezswz2ovl@development> <20200719151945.p6iaexethuplxxic@development> <20200804151743.dbobvzovtnpgfpn7@development> <20200807162701.v7lyzun32lqku3md@development> <20200905014648.GB17191@paquier.xyz> <20200905232042.4jegjfjfpzxsvowb@development> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii; format=flowed Content-Disposition: inline In-Reply-To: List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Precedence: bulk On Wed, Sep 09, 2020 at 12:04:28PM -0400, John Naylor wrote: >On Sat, Sep 5, 2020 at 7:21 PM Tomas Vondra > wrote: >> >> OK, here is a rebased version. Most of the breakage was due to changes >> to the BRIN sgml docs. > >Hi Tomas, > >I plan on trying some different queries on different data >distributions to get a sense of when the planner chooses a >multi-minmax index, and whether the choice is good. > >Just to start, I used the artificial example in [1], but scaled down a >bit to save time. Config is at the default except for: >shared_buffers = 1GB >random_page_cost = 1.1; >effective_cache_size = 4GB; > >create table t (a bigint, b int) with (fillfactor=95); > >insert into t select i + 1000*random(), i+1000*random() > from generate_series(1,10000000) s(i); > >update t set a = 1, b = 1 where random() < 0.001; >update t set a = 10000000, b = 10000000 where random() < 0.001; > >analyze t; > >create index on t using brin (a); >CREATE INDEX >Time: 1631.452 ms (00:01.631) > >explain analyze select * from t > where a between 1923300::int and 1923600::int; > > QUERY PLAN >-------------------------------------------------------------------------------------------------------------------------- > Bitmap Heap Scan on t (cost=16.10..43180.43 rows=291 width=12) >(actual time=217.770..1131.366 rows=288 loops=1) > Recheck Cond: ((a >= 1923300) AND (a <= 1923600)) > Rows Removed by Index Recheck: 9999712 > Heap Blocks: lossy=56819 > -> Bitmap Index Scan on t_a_idx (cost=0.00..16.03 rows=22595 >width=0) (actual time=3.054..3.055 rows=568320 loops=1) > Index Cond: ((a >= 1923300) AND (a <= 1923600)) > Planning Time: 0.328 ms > Execution Time: 1131.411 ms >(8 rows) > >Now add the multi-minmax: > >create index on t using brin (a int8_minmax_multi_ops); >CREATE INDEX >Time: 6521.026 ms (00:06.521) > >The first interesting thing is, with both BRIN indexes available, the >planner still chooses the conventional BRIN index. Only when I disable >it, does it choose the multi-minmax index: > >explain analyze select * from t > where a between 1923300::int and 1923600::int; > > QUERY PLAN >------------------------------------------------------------------------------------------------------------------------- > Bitmap Heap Scan on t (cost=68.10..43160.86 rows=291 width=12) >(actual time=1.835..4.196 rows=288 loops=1) > Recheck Cond: ((a >= 1923300) AND (a <= 1923600)) > Rows Removed by Index Recheck: 22240 > Heap Blocks: lossy=128 > -> Bitmap Index Scan on t_a_idx1 (cost=0.00..68.03 rows=22523 >width=0) (actual time=0.691..0.691 rows=1280 loops=1) > Index Cond: ((a >= 1923300) AND (a <= 1923600)) > Planning Time: 0.250 ms > Execution Time: 4.244 ms >(8 rows) > >I wonder if this is a clue that something in the costing unfairly >penalizes a multi-minmax index. Maybe not enough to matter in >practice, since I wouldn't expect a user to put different kinds of >index on the same column. > I think this is much more an estimation issue than a costing one. Notice that in the "regular" BRIN minmax index we have this: -> Bitmap Index Scan on t_a_idx (cost=0.00..16.03 rows=22595 width=0) (actual time=3.054..3.055 rows=568320 loops=1) while for the multi-minmax we have this: -> Bitmap Index Scan on t_a_idx1 (cost=0.00..68.03 rows=22523 width=0) (actual time=0.691..0.691 rows=1280 loops=1) So yes, the multi-minmax index is costed a bit higher, mostly because the index is a bit larger. (There's also a tweak to the correlation, but that does not make much difference because it's just 0.99 vs. 1.0.) The main difference is that for minmax the bitmap index scan actually matches ~586k rows (a bit confusing, considering the heap scan has to process almost 10M rows during recheck). But the multi-minmax only matches ~1300 rows, with a recheck of 22k. I'm not sure how to consider this during costing, as we only see these numbers at execution time. One way would be to also consider "size" of the ranges (i.e. max-min) vs. range of the whole column. But that's not something we already have. I'm not sure how troublesome this issue really is - I don't think people are very likely to have both minmax and multi-minmax indexes on the same column. >The second thing is, with parallel seq scan, the query is faster than >a BRIN bitmap scan, with this pathological data distribution, but the >planner won't choose it unless forced to: > >set enable_bitmapscan = 'off'; >explain analyze select * from t > where a between 1923300::int and 1923600::int; > QUERY PLAN >----------------------------------------------------------------------------------------------------------------------- > Gather (cost=1000.00..120348.10 rows=291 width=12) (actual >time=372.766..380.364 rows=288 loops=1) > Workers Planned: 2 > Workers Launched: 2 > -> Parallel Seq Scan on t (cost=0.00..119319.00 rows=121 >width=12) (actual time=268.326..366.228 rows=96 loops=3) > Filter: ((a >= 1923300) AND (a <= 1923600)) > Rows Removed by Filter: 3333237 > Planning Time: 0.089 ms > Execution Time: 380.434 ms >(8 rows) > I think this is the same root cause - the planner does not realize how bad the minmax index actually is in this case, so it uses a bit too optimistic estimate for costing. And then it has to do essentially seqscan with extra work for bitmap index/heap scan. regards -- Tomas Vondra http://www.2ndQuadrant.com PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services