Received: from malur.postgresql.org ([217.196.149.56]) by arkaria.postgresql.org with esmtp (Exim 4.84_2) (envelope-from ) id 1eMhWv-0001md-1c for pgsql-performance@arkaria.postgresql.org; Wed, 06 Dec 2017 21:47:01 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.84_2) (envelope-from ) id 1eMhWu-0006JK-C3 for pgsql-performance@arkaria.postgresql.org; Wed, 06 Dec 2017 21:47:00 +0000 Received: from makus.postgresql.org ([2001:4800:1501:1::229]) by malur.postgresql.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA384:256) (Exim 4.84_2) (envelope-from ) id 1eMhWt-0006JB-Tc for pgsql-performance@lists.postgresql.org; Wed, 06 Dec 2017 21:47:00 +0000 Received: from mail-it0-x244.google.com ([2607:f8b0:4001:c0b::244]) by makus.postgresql.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA1:256) (Exim 4.89) (envelope-from ) id 1eMhWq-0000bS-15 for pgsql-performance@lists.postgresql.org; Wed, 06 Dec 2017 21:46:58 +0000 Received: by mail-it0-x244.google.com with SMTP id d16so9772380itj.1 for ; Wed, 06 Dec 2017 13:46:55 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=telsasoft-com.20150623.gappssmtp.com; s=20150623; h=date:from:to:cc:subject:message-id:references:mime-version :content-disposition:in-reply-to:user-agent; bh=eRzYQ1dDcZrA2+smG2CaYiSM2Srl9yLSDHzRp6qm4dQ=; b=rY9lQhVLNvfMav10UkXEPQyiXGF+6kfJq8x52lbbBULzGneoEFRwhuZKPbz3xS228Y GY633c17CdVxDCzZLtU8VJZYwN2bbGwKb2BZHgkuu0wBnqNdw5efpnVH2mqurwxthM5z 6loa4J+ur+tyUSXt5qXzOVZBabkBeJdlfF/nDoV1x/ELQshy9EtWHvfwwoUGvt6crnZ0 qG2iaj11zNZMXMEaAODZVhkhvzR+64svGBbLmM+EQcjsH5FuNWmvZs2OFhHI2OLaSM29 LGrejLWETQOknQXbCxPGJAEWhMb6ER9BuF8VwoWOrBdfwklpmEMybmtufsygz7dWsZ8i 0lbw== 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:user-agent; bh=eRzYQ1dDcZrA2+smG2CaYiSM2Srl9yLSDHzRp6qm4dQ=; b=QpvNuXQJguDqg0C+9fv5EExdeBbwbnTLdAXciRJilZAD81Fj4S5r7/iTZt+pFiN+Pu xasHgSa1xXrQO02h5PB/2MIWH8uE+1wi30vISndJlBnSm6kagV/I1fYDi3j1eUlWroWH I0kO4seatJPeXntFTnWTeAO5UpROW/rz2OB7QmhofcEkXnwVee7/yXB6gm5siHc7mkoW jXoZrMNehUU1Yjt7QATUDAvmyz2QcpJjZYgOiJz5unnXE/baMRZGT+NpuAVG+N9hq/iI UCkG75gXjgtKHYBm+G34Oy7oNzcF6Aioo8pznXSkFQMWGYM01QZMhHPxMEOa4QajsAZs bTPA== X-Gm-Message-State: AKGB3mJBeTrPr8OOgttsbNH1mYSPrwd0aL+eLKEh++2Wt38n1dbf+IXF hQn+cz5XvsO7SBmybG3Fwj/SWA== X-Google-Smtp-Source: AGs4zMboA9TcVTf2y+tOGAh8LtgSLri34Dg/Gf0smZ5W1F9y+xHzndKiq69j/OXJTd1nF8f48Ti7WA== X-Received: by 10.107.104.6 with SMTP id d6mr10095386ioc.56.1512596814544; Wed, 06 Dec 2017 13:46:54 -0800 (PST) Received: from pryzbyj (charmander.telsasoft.com. [50.244.222.1]) by smtp.gmail.com with ESMTPSA id 76sm2009445itk.23.2017.12.06.13.46.53 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 06 Dec 2017 13:46:53 -0800 (PST) Received: by pryzbyj (Postfix, from userid 1000) id A939B80105E; Wed, 6 Dec 2017 15:46:52 -0600 (CST) Date: Wed, 6 Dec 2017 15:46:52 -0600 From: Justin Pryzby To: Tom Lane Cc: Jeff Janes , Vitaliy Garnashevich , pgsql-performance@lists.postgresql.org Subject: Re: Bitmap scan is undercosted? - overestimated correlation and cost_index Message-ID: <20171206214652.GA13889@telsasoft.com> References: <18188.1512258290@sss.pgh.pa.us> <20171203040430.GC14008@telsasoft.com> <12766.1512343900@sss.pgh.pa.us> <14438.1512499811@sss.pgh.pa.us> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <14438.1512499811@sss.pgh.pa.us> User-Agent: Mutt/1.5.23 (2014-03-12) List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Precedence: bulk On Tue, Dec 05, 2017 at 01:50:11PM -0500, Tom Lane wrote: > Jeff Janes writes: > > On Dec 3, 2017 15:31, "Tom Lane" wrote: > >> Jeff Janes writes: > >>> But I do see that ties within the logical order of the column values are > >>> broken to agree with the physical order. That is wrong, right? Is there > >>> any argument that this is desirable? > > >> Uh ... what do you propose doing instead? We'd have to do something with > >> ties, and it's not so obvious this way is wrong. > > > Let them be tied. ... > I thought some more about this. What we really want the correlation stat > to do is help us estimate how randomly an index-ordered scan will access > the heap. If the values we've sampled are all unequal then there's no > particular issue. However, if we have some group of equal values, we > do not really know what order an indexscan will visit them in. The > existing correlation calculation is making the *most optimistic possible* > assumption, that such a group will be visited exactly in heap order --- > and that assumption isn't too defensible. I'm interested in discusstion regarding bitmap cost, since it would have helped our case discussed here ~18 months ago: https://www.postgresql.org/message-id/flat/20160524173914.GA11880%40telsasoft.com#20160524173914.GA11880@telsasoft.com ...but remember: in Vitaliy's case (as opposed to mine), the index scan is *faster* but being estimated at higher cost than bitmap (I have to keep reminding myself). So the rest of this discussion is about the overly-optimistic cost estimate of index scans, which moves in the opposite direction for this reported problem. For the test cases I looked at, index scans were used when RPC=1 and redundant conditions were avoided, so I'm not sure if there's any remaining issue (but I haven't looked at the latest cases Vitaliy sent). > In any case, given that we do this calculation without regard > to any specific index, One solution is to compute stats (at least correlation) for all indices, not just expr inds. I did that earlier this year while throwing around/out ideas. https://www.postgresql.org/message-id/20170707234119.GN17566%40telsasoft.com > We do have an idea, from the data we have, whether the duplicates are close > together in the heap or spread all over. I think you just mean pg_stats.correlation for all values, not just duplicates (with the understanding that duplicates might be a large fraction of the tuples, and high weight in correlation). Another issue I noted in an earlier thread is that as table sizes increase, the existing correlation computation approaches 1 for correlated insertions, (like "append-only" timestamps clustered around now()), due to ANALYZE sampling a fraction of the table, and thereby representing only large-scale correlation, and, to an increasing degree, failing to represent small-scale variations between adjacent index TIDs, which has real cost (and for which the mitigation by cache effects probably decreases WRT table size, too). I think any solution needs to handle this somehow. Generated data demonstrating this (I reused this query so it's more complicated than it needs to be): [pryzbyj@database ~]$ time for sz in 9999{,9{,9{,9{,9}}}} ; do psql postgres -tc "DROP TABLE IF EXISTS t; CREATE TABLE t(i float, j int); CREATE INDEX ON t(i);INSERT INTO t SELECT i/99999.0+pow(2,(-random())) FROM generate_series(1,$sz) i ORDER BY i; ANALYZE t; SELECT $sz, correlation, most_common_freqs[1] FROM pg_stats WHERE attname='i' AND tablename='t'"; done 9999 | 0.187146 | 99999 | 0.900629 | 999999 | 0.998772 | 9999999 | 0.999987 | Trying to keep it all in my own head: For sufficiently large number of pages, bitmap scan should be preferred to idx scan due to reduced random-page-cost outweighing its overhead in CPU cost. Probably by penalizing index scans, not discounting bitmap scans. Conceivably a correlation adjustment can be conditionalized or weighted based on index_pages_fetched() ... x = ln (x/999999); if (x>1) correlation/=x; I think one could look at the fraction of duplicated index keys expected to be returned: if we expect to return 1000 tuples, with 200 duplicates from MCV, cost_index would multiply correlation by (1 - 200/1000), meaning to use something closer to max_IO_cost rather than min_IO_cost. I imagine it'd be possible to limit to only those MCVs which pass quals - if none pass, then there may be few tuples returned, so apply no correction to (additionally) penalize index scan. In my tests, at one point I implemented idx_corr_fudge(), returning a value like "fragmentation" from pgstatindex (which I'm sure is where I got the phrase when reporting the problem). That only uses the leaf nodes' "next" pointer, and not the individual tuples, which probably works if there's a sufficiently number of repeated keys. I think that's all for now.. Justin