Received: from malur.postgresql.org ([217.196.149.56]) by arkaria.postgresql.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA1:256) (Exim 4.92) (envelope-from ) id 1jCmsk-0001X2-Fg for pgsql-hackers@arkaria.postgresql.org; Fri, 13 Mar 2020 16:09:54 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.89) (envelope-from ) id 1jCmsj-0005VT-0P for pgsql-hackers@arkaria.postgresql.org; Fri, 13 Mar 2020 16:09:53 +0000 Received: from makus.postgresql.org ([2001:4800:3e1:1::229]) by malur.postgresql.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA1:256) (Exim 4.89) (envelope-from ) id 1jCmsi-0005Uw-KG for pgsql-hackers@lists.postgresql.org; Fri, 13 Mar 2020 16:09:52 +0000 Received: from mail-wr1-x441.google.com ([2a00:1450:4864:20::441]) by makus.postgresql.org with esmtps (TLS1.3:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.92) (envelope-from ) id 1jCmse-0002DG-Pc for pgsql-hackers@lists.postgresql.org; Fri, 13 Mar 2020 16:09:51 +0000 Received: by mail-wr1-x441.google.com with SMTP id x11so8054338wrv.5 for ; Fri, 13 Mar 2020 09:09:48 -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=+aQ7OOUE18heiY6cv+r+eStV5pSCwuAxwC0uL1FTmWU=; b=L5Tu4gTDtPkqyqvGmXllIPpZtR1W/1oXbIelfPzXsrLQI+pgh4H0yBl6vJ+dOrSAhV 17loKjLnOxT/xjQ/Epp6YWCK2S71xg5LK8myOkpUoKXRE6rzUdZtZKb2nHWCCR8t1y0t R0PFa4Ex6f3cc507RkXoi1PNjr2NzKSu9w0f21eBbQl0sj+s/bAUypgiExfao5XYHP1k AfV6zBS9X8uhWuBoYgskyBtPlMVHotEXgJCICfj0GrJUMU9UKMccM65oKF97zE+Hgz8q nTrdS5YX0+fx+Q8uyGHoNqvUuftIyicpTCjxdHOLE0AEPJkA+vaE2IltVZtsmfr+DHOC rk1g== 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=+aQ7OOUE18heiY6cv+r+eStV5pSCwuAxwC0uL1FTmWU=; b=tMMzD6drJFsZoXCC+ssm+oFUDUr+PYnaPqPUPvdwSbFY8OPDCYRTcnoDaJo54kPD9g ax1ZL1HosmyRIhb0WgG/YMmVfwN5N2GbVUPrg9jBkJ/AExQZTom8uFlVxnk6R/r7Pi/V PD1bsL1YklhfNPUPomXdz37+asPdjW+XXUiyPBPAK14WTcSP/J+rjpa/nz5sQRagVkHf 6gkumK3WpaWHh3cIKZESKs0ieiuDDCWIyZypUnlil+8ZQ8OV5aAZMiP2ReVivvyy7pq0 y/tI+OM2g5K9IGLzWPS/Xv94QMxX3oVFWLcoogOdeJjN6HQ1iTwIoMeC1ATzUpjSak0T V5Rg== X-Gm-Message-State: ANhLgQ2ckRBWlE7SLUAIldh++06m3oDiXenJIXHf1hMsnl1lkcCEAo9H bF5mIiG6KK2DyG1vTGo/lAzKdQ== X-Google-Smtp-Source: ADFU+vtujqpeLF3B/BT1h15buHvQdk2Iqc02NO1FLX581dDG5RkIQOsAzXAY6WWD0L4msU6rF9hXpA== X-Received: by 2002:a5d:6289:: with SMTP id k9mr14164569wru.36.1584115787234; Fri, 13 Mar 2020 09:09:47 -0700 (PDT) Received: from localhost (ip-86-49-253-92.net.upcbroadband.cz. [86.49.253.92]) by smtp.gmail.com with ESMTPSA id w67sm13534198wmb.41.2020.03.13.09.09.46 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 13 Mar 2020 09:09:46 -0700 (PDT) Date: Fri, 13 Mar 2020 17:09:44 +0100 From: Tomas Vondra To: Dean Rasheed Cc: Pierre Ducroquet , PostgreSQL Hackers Subject: Re: PATCH: add support for IN and @> in functional-dependency statistics use Message-ID: <20200313160944.aqrbkyf7tkasoxfk@development> References: <13902317.Eha0YfKkKy@pierred-pdoc> <20200201142446.aq5zf3gawj3ynrc2@development> <3937607.jCdSCb7NGl@pierred-pdoc> <20200202184134.swoqkqlqorqolrqv@development> <20200312173047.stp55sxoj4sipn7q@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 Fri, Mar 13, 2020 at 08:42:49AM +0000, Dean Rasheed wrote: >On Thu, 12 Mar 2020 at 17:30, Tomas Vondra wrote: >> >> I'm sorry, but I don't see how we could do this for arbitrary clauses. I >> think we could do that for clauses that have equality semantics and >> reference column values as a whole. So I think it's possible to do this >> for IN clauses (which is what the first part of the patch does), but I >> don't think we can do it for the containment operator. >> >> I.e. we can do that for >> >> WHERE a IN (...) AND b IN (...) >> > >Hmm, the difficulty always comes back to the compatibility of the >clauses though. It's easy to come up with artificial examples for >which functional dependencies come up with bad estimates, even with >just = and IN (...) operators. For example, given a perfect >correlation like > > a | b > ------- > 1 | 1 > 2 | 2 > 3 | 3 > : | : > >you only need to write a query like "WHERE a IN (1,3,5,7,9,...) AND b >IN (2,4,6,8,...)" to get a very bad estimate from functional >dependencies. > >However, I don't think such artificial examples are that useful. I >think you have to think in terms of real data distributions together >with real queries expected to go with them. For example: > >Using the OP's original example of a multi-tenant system, you might >well have a table with columns (product_type, tenant_id) and a >functional dependency product_type => tenant_id. In that case, it >could well be very useful in optimising queries like "WHERE >product_type IN (X,Y,Z) AND tenant_id = 123". > >But this isn't necessarily limited to = and IN (...). For example, >consider a table with UK-based geographic data with columns (location >point, postcode text). Then there would be a strong functional >dependency location => postcode (and possibly also the other way >round, depending on how dense the points were). That dependency could >be used to estimate much more general queries like "WHERE location <@ >some_area AND postcode ~ '^CB.*'", where there may be no useful stats >on location, but a histogram on postcode might give a reasonable >estimate. > >This also extends to inequalities. For example a table with columns >(weight, category) might have a strong functional dependency weight => >category. Then a query like "WHERE weight > 10 AND weight < 20 AND >category = 'large'" could get a decent estimate from a histogram on >the weight column, and then use the functional dependency to note that >that implies the category. Note that such an example would work with >my patch from the other thread, because it groups clauses by column, >and uses clauselist_selectivity_simple() on them. So in this case, the >clauses "weight > 10 AND weight < 20" would be estimated together, and >would be able to make use of the RangeQueryClause code. > >Of course, it's equally easy to come up with counter-example queries >for any of those examples, where using the functional dependency would >produce a poor estimate. Ultimately, it's up to the user to decide >whether or not to build functional dependency statistics, and that >decision needs to be based not just on the data distribution, but also >on the types of queries expected. > Well, yeah. I'm sure we can produce countless examples where applying the functional dependencies to additional types of clauses helps a lot. I'm somewhat hesitant to just drop any restrictions, though, because it's equally simple to produce examples with poor results. The main issue I have with just applying dependencies to arbitrary clauses is it uses "degree" computed for the value as a whole, and just uses it to estimate dependency between pieces of the values. The IN() clause does not have this problem, the other cases like @> or pattern matching do. >Given the timing though, perhaps it is best to limit this to IN (..) >clauses for PG13, and we can consider other possibilities later. > Yeah, I was gonna propose the same thing. I'll get the IN bit committed shortly (both for dependencies and MCV), improved handling of OR clauses and some additional regression tests to increase the coverage. Then we can discuss these improvement in more detail for PG14. regards -- Tomas Vondra http://www.2ndQuadrant.com PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services