Received: from malur.postgresql.org ([217.196.149.56]) by arkaria.postgresql.org with esmtp (Exim 4.84_2) (envelope-from ) id 1eVA8R-00035w-AA for pgsql-performance@arkaria.postgresql.org; Sat, 30 Dec 2017 05:56:43 +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 1eVA8Q-00077L-2r for pgsql-performance@arkaria.postgresql.org; Sat, 30 Dec 2017 05:56:42 +0000 Received: from magus.postgresql.org ([2a02:c0:301:0:ffff::29]) by malur.postgresql.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA384:256) (Exim 4.84_2) (envelope-from ) id 1eVA8P-00077B-Ri for pgsql-performance@lists.postgresql.org; Sat, 30 Dec 2017 05:56:41 +0000 Received: from mail-io0-x241.google.com ([2607:f8b0:4001:c06::241]) by magus.postgresql.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA1:256) (Exim 4.89) (envelope-from ) id 1eVA8H-0006k6-OV for pgsql-performance@postgresql.org; Sat, 30 Dec 2017 05:56:40 +0000 Received: by mail-io0-x241.google.com with SMTP id q188so18643045iod.1 for ; Fri, 29 Dec 2017 21:56:33 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=telsasoft-com.20150623.gappssmtp.com; s=20150623; h=date:from:to:subject:message-id:mime-version:content-disposition :user-agent; bh=ieacd/w81meuCVs0Jj8zC5ludkA7YjAYKW36TjO78g0=; b=Ur4yQTcsWuOhpss78YQxr0pMC5L+XGrt6urf7Tw0OsiK4PAbXZFjAIq4PEIlkQCRMq SmoW6n2xrMPjqS7NEammQvSnPOVoCXIJy++9VbmCf5K4K4AGU2kvRDibNMUvULCXBycE Tq0CBDGs/Ek5KSVPE+v1Tbbtc9eBf0SschAq2MYVzduZ5KUV897SuDP2tZqeF5QJ3OhS uza25GjzxbO9c3fdAdVU9/5JL18xtbEZDCRSgQMqziXiEAdmfDXsGclOHkBnLHiC7w4k a5EGRR+XWORAfYcyqKjzGiXgEciOOklUg0OP2VAmv3ShSt00+FCHa2JmE8b30RRf4tSa +VsQ== 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:subject:message-id:mime-version :content-disposition:user-agent; bh=ieacd/w81meuCVs0Jj8zC5ludkA7YjAYKW36TjO78g0=; b=h/QuSa04sckHpzj1v00ZYGuEtjvoz/U7fhXv5+S6rb53B9F3nAnPojaUVZ1bDIsSbT qcEjYt4yo6CMfykcQ4E5Dc95fYWI3GzlWNjZEoArrERc5rT7s6XplrljvJ4myBA3GgL0 bs/JiUA/PrsBAbFntpfDUU9V8/8G9dKyC2juGXqdw1Npe/UGmizfZKjvgnwubCu1G3AI 4eL+Z9OORaglXZghkdWgh6KEuzsWA0TuPcDH1fZjLtg9zUsF/VOgJ3ZGn1JUS48QVDG8 jK3M4v9g4L+7OAgpoLs6beLmYY8rMTLe0MOJoEaxj3wQzz9OUGlDFKmWG8DJpGrFm7Jq N1Fg== X-Gm-Message-State: AKGB3mKPFzl6bx+lwdoujT205KwzYI9kotSn/RyD2pFWz7wiz/49yE8l ps/6vSf77F+otzjNohjEt+vYI19h984= X-Google-Smtp-Source: ACJfBos8moFLKcjS4ncO6M1nx5V8mnoTJFpljTpWYJRBRJ13W7v2imNRNp1mV9Nl5JjohpqybOTWGQ== X-Received: by 10.107.111.17 with SMTP id k17mr32880544ioc.202.1514613391727; Fri, 29 Dec 2017 21:56:31 -0800 (PST) Received: from pryzbyj (charmander.telsasoft.com. [50.244.222.1]) by smtp.gmail.com with ESMTPSA id 72sm15746882iol.64.2017.12.29.21.56.31 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 29 Dec 2017 21:56:31 -0800 (PST) Received: by pryzbyj (Postfix, from userid 1000) id 8BF758011FC; Fri, 29 Dec 2017 23:56:30 -0600 (CST) Date: Fri, 29 Dec 2017 23:56:30 -0600 From: Justin Pryzby To: pgsql-performance@postgresql.org Subject: analyze stats: child vs parent Message-ID: <20171230055630.GF4172@telsasoft.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline User-Agent: Mutt/1.5.23 (2014-03-12) List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Precedence: bulk This topic is confusing to lots of people, usually including myself, so I'm hoping to clarify it at least to myself, and maybe provide a good reference or doc update for others in the future. autovacuum/analyze automatically scans tables being inserted/updated/deleted and updates their statistics in pg_class and pg_statistic. Since PG 9.0 [0,1], ANALYZE (can) include stats of child tables along with stats of the (ONLY) parent table. But, autoanalyze still doesn't know to analyze (typical) empty parent tables, which need to be manually ANALYZEd to include stats for their children. ...which leaves one wondering: "which stats are being used?, and why are we keeping two and apparently sometimes not looking at both/either" ? I think the explanation is this: - Parent table stats without children (pg_statistic.stainherit='f') [2] are used if you query SELECT ONLY). Simple enough. - Postgres uses rowcount estimate as the primary component of query planning. When planning a query involving a parent table, its rowcount estimate is obtained as the sum of the rowcounts for its child nodes (appendrels) - if a table is excluded by query exclusion, it doesn't even show up in the plan, and if only a fraction of its rows are returned due to a restrictive clause, that's reflected in its rowcount estimate and in the estimate of the parent. So child tables need to be analyzed for their rowcount (and also for their column stats which affect rowcount). - But, column stats (ndistinct, most-common values, and histogram) are relatively big, and there's nothing implemented (yet) to intelligently combine them across child tables in a query. So postgres, having obtained a rowcount estimate for parent tables involved in a query, having determined how (or one way) to join the tables, needs to determine how many rows are expected to result be output by a join, which uses on parent table's column stats (ndistinct, MCV list, histogram). Is that mostly right ? Toward the future: maybe, with declarative partitioning, combining selectivities as in [3] is possible now without objectionable planning overhead (?) Justin References [0] https://www.postgresql.org/docs/9.0/static/release-9-0.html#AEN102560 [1] https://www.postgresql.org/message-id/flat/2674.1262040064%40sss.pgh.pa.us#2674.1262040064@sss.pgh.pa.us [2] https://www.postgresql.org/docs/current/static/catalog-pg-statistic.html [3] https://www.postgresql.org/message-id/flat/7363.1426537103%40sss.pgh.pa.us#7363.1426537103@sss.pgh.pa.us more: https://www.postgresql.org/message-id/7806.1310233430@sss.pgh.pa.us https://www.postgresql.org/message-id/4B3875C6020000250002D97D@gw.wicourts.gov https://www.postgresql.org/message-id/29559.1287206562%40sss.pgh.pa.us