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.89) (envelope-from ) id 1gubYQ-0000Sg-AI for pgsql-hackers@arkaria.postgresql.org; Fri, 15 Feb 2019 11:21:14 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.89) (envelope-from ) id 1gubYN-0006Ut-3V for pgsql-hackers@arkaria.postgresql.org; Fri, 15 Feb 2019 11:21:11 +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_SHA1:256) (Exim 4.89) (envelope-from ) id 1gubYM-0006Ul-Sb for pgsql-hackers@lists.postgresql.org; Fri, 15 Feb 2019 11:21:10 +0000 Received: from tama50.ecl.ntt.co.jp ([129.60.39.147]) by magus.postgresql.org with esmtp (Exim 4.89) (envelope-from ) id 1gubYF-0000Nu-GG for pgsql-hackers@postgresql.org; Fri, 15 Feb 2019 11:21:09 +0000 Received: from vc2.ecl.ntt.co.jp (vc2.ecl.ntt.co.jp [129.60.86.154]) by tama50.ecl.ntt.co.jp (8.13.8/8.13.8) with ESMTP id x1FBL2UP017595 for ; Fri, 15 Feb 2019 20:21:02 +0900 Received: from vc2.ecl.ntt.co.jp (localhost [127.0.0.1]) by vc2.ecl.ntt.co.jp (Postfix) with ESMTP id 05518639162 for ; Fri, 15 Feb 2019 20:21:02 +0900 (JST) Received: from jcms-pop21.ecl.ntt.co.jp (jcms-pop21.ecl.ntt.co.jp [129.60.87.134]) by vc2.ecl.ntt.co.jp (Postfix) with ESMTP id E49EB63914F for ; Fri, 15 Feb 2019 20:21:01 +0900 (JST) Received: from [IPv6:::1] (unknown [129.60.241.75]) by jcms-pop21.ecl.ntt.co.jp (Postfix) with ESMTPSA id DF44040072A for ; Fri, 15 Feb 2019 20:21:01 +0900 (JST) Message-ID: <5C66A056.60007@lab.ntt.co.jp> Date: Fri, 15 Feb 2019 20:19:50 +0900 From: Etsuro Fujita User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:11.0) Gecko/20120327 Thunderbird/11.0.1 MIME-Version: 1.0 Subject: postgres_fdw: another oddity in costing aggregate pushdown paths Content-Type: multipart/mixed; boundary="------------010809070104010204000506" X-CC-Mail-RelayStamp: 1 To: Pg Hackers X-TM-AS-MML: disable List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Precedence: bulk This is a multi-part message in MIME format. --------------010809070104010204000506 Content-Type: text/plain; charset=ISO-2022-JP Content-Transfer-Encoding: 7bit As mentioned in the near thread, I think there is another oversight in the cost estimation for aggregate pushdown paths in postgres_fdw, IIUC. When costing an aggregate pushdown path using local statistics, we re-use the estimated costs of implementing the underlying scan/join relation, cached in the relation's PgFdwRelationInfo (ie, rel_startup_cost and rel_total_cost). Since these costs wouldn't yet contain the costs of evaluating the final scan/join target, as tlist replacement by apply_scanjoin_target_to_paths() is performed afterwards. So I think we need to adjust these costs so that the tlist eval costs are included, but ISTM that estimate_path_cost_size() forgot to do so. Attached is a patch for fixing this issue. Best regards, Etsuro Fujita --------------010809070104010204000506 Content-Type: text/x-patch; name="another-fix-postgres-fdw-grouping-path-cost.patch" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="another-fix-postgres-fdw-grouping-path-cost.patch" *** a/contrib/postgres_fdw/postgres_fdw.c --- b/contrib/postgres_fdw/postgres_fdw.c *************** *** 2705,2716 **** estimate_path_cost_size(PlannerInfo *root, --- 2705,2719 ---- } else if (IS_UPPER_REL(foreignrel)) { + RelOptInfo *outerrel = fpinfo->outerrel; PgFdwRelationInfo *ofpinfo; AggClauseCosts aggcosts; double input_rows; int numGroupCols; double numGroups = 1; + Assert(outerrel); + /* * This cost model is mixture of costing done for sorted and * hashed aggregates in cost_agg(). We are not sure which *************** *** 2719,2725 **** estimate_path_cost_size(PlannerInfo *root, * and all finalization and run cost are added in total_cost. */ ! ofpinfo = (PgFdwRelationInfo *) fpinfo->outerrel->fdw_private; /* Get rows and width from input rel */ input_rows = ofpinfo->rows; --- 2722,2728 ---- * and all finalization and run cost are added in total_cost. */ ! ofpinfo = (PgFdwRelationInfo *) outerrel->fdw_private; /* Get rows and width from input rel */ input_rows = ofpinfo->rows; *************** *** 2772,2782 **** estimate_path_cost_size(PlannerInfo *root, /*----- * Startup cost includes: ! * 1. Startup cost for underneath input relation * 2. Cost of performing aggregation, per cost_agg() *----- */ startup_cost = ofpinfo->rel_startup_cost; startup_cost += aggcosts.transCost.startup; startup_cost += aggcosts.transCost.per_tuple * input_rows; startup_cost += aggcosts.finalCost.startup; --- 2775,2787 ---- /*----- * Startup cost includes: ! * 1. Startup cost for underneath input relation, adjusted for ! * tlist replacement by apply_scanjoin_target_to_paths() * 2. Cost of performing aggregation, per cost_agg() *----- */ startup_cost = ofpinfo->rel_startup_cost; + startup_cost += outerrel->reltarget->cost.startup; startup_cost += aggcosts.transCost.startup; startup_cost += aggcosts.transCost.per_tuple * input_rows; startup_cost += aggcosts.finalCost.startup; *************** *** 2784,2794 **** estimate_path_cost_size(PlannerInfo *root, /*----- * Run time cost includes: ! * 1. Run time cost of underneath input relation * 2. Run time cost of performing aggregation, per cost_agg() *----- */ run_cost = ofpinfo->rel_total_cost - ofpinfo->rel_startup_cost; run_cost += aggcosts.finalCost.per_tuple * numGroups; run_cost += cpu_tuple_cost * numGroups; --- 2789,2801 ---- /*----- * Run time cost includes: ! * 1. Run time cost of underneath input relation, adjusted for ! * tlist replacement by apply_scanjoin_target_to_paths() * 2. Run time cost of performing aggregation, per cost_agg() *----- */ run_cost = ofpinfo->rel_total_cost - ofpinfo->rel_startup_cost; + run_cost += outerrel->reltarget->cost.per_tuple * input_rows; run_cost += aggcosts.finalCost.per_tuple * numGroups; run_cost += cpu_tuple_cost * numGroups; --------------010809070104010204000506--