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 1gmzkA-0008J7-Nm for pgsql-hackers@arkaria.postgresql.org; Fri, 25 Jan 2019 11:33: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 1gmzk8-0000jU-TT for pgsql-hackers@arkaria.postgresql.org; Fri, 25 Jan 2019 11:33:52 +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 1gmzk8-0000jM-JM for pgsql-hackers@lists.postgresql.org; Fri, 25 Jan 2019 11:33:52 +0000 Received: from tama500.ecl.ntt.co.jp ([129.60.39.148]) by makus.postgresql.org with esmtp (Exim 4.89) (envelope-from ) id 1gmzk5-00086E-7t for pgsql-hackers@postgresql.org; Fri, 25 Jan 2019 11:33:51 +0000 Received: from vc1.ecl.ntt.co.jp (vc1.ecl.ntt.co.jp [129.60.86.153]) by tama500.ecl.ntt.co.jp (8.13.8/8.13.8) with ESMTP id x0PBXlkw012642 for ; Fri, 25 Jan 2019 20:33:47 +0900 Received: from vc1.ecl.ntt.co.jp (localhost [127.0.0.1]) by vc1.ecl.ntt.co.jp (Postfix) with ESMTP id 204D2EA8452 for ; Fri, 25 Jan 2019 20:33:47 +0900 (JST) Received: from jcms-pop21.ecl.ntt.co.jp (jcms-pop21.ecl.ntt.co.jp [129.60.87.134]) by vc1.ecl.ntt.co.jp (Postfix) with ESMTP id 15DDDEA8442 for ; Fri, 25 Jan 2019 20:33:47 +0900 (JST) Received: from [IPv6:::1] (unknown [129.60.241.75]) by jcms-pop21.ecl.ntt.co.jp (Postfix) with ESMTPSA id 107E1400170 for ; Fri, 25 Jan 2019 20:33:47 +0900 (JST) Message-ID: <5C4AF3F3.4060409@lab.ntt.co.jp> Date: Fri, 25 Jan 2019 20:33:07 +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: estimate_path_cost_size fails to re-use cached costs Content-Type: multipart/mixed; boundary="------------050400070102040602000708" 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. --------------050400070102040602000708 Content-Type: text/plain; charset=ISO-2022-JP Content-Transfer-Encoding: 7bit Hi, I noticed yet another thing while updating the patch for pushing down ORDER BY LIMIT. Let me explain. When costing foreign paths on the basis of local statistics, we calculate/cache the costs of an unsorted foreign path, and re-use them to estimate the costs of presorted foreign paths, as shown below. BUT: we fail to re-use them for some typical queries, such as "select * from ft1 order by a", due to fpinfo->rel_startup_cost=0, leading to doing the same cost calculation repeatedly. /* * We will come here again and again with different set of pathkeys * that caller wants to cost. We don't need to calculate the cost of * bare scan each time. Instead, use the costs if we have cached them * already. */ if (fpinfo->rel_startup_cost > 0 && fpinfo->rel_total_cost > 0) { startup_cost = fpinfo->rel_startup_cost; run_cost = fpinfo->rel_total_cost - fpinfo->rel_startup_cost; } I think we should use "fpinfo->rel_startup_cost >= 0" here, not "fpinfo->rel_startup_cost > 0". Also, it would be possible that the total cost calculated is zero in corner cases (eg, seq_page_cost=0 and cpu_tuple_cost=0 for the example), so I think we should change the total cost part as well. Attached is a patch for that. Best regards, Etsuro Fujita --------------050400070102040602000708 Content-Type: text/x-patch; name="yet-another-fix-for-estimate_path_cost_size.patch" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="yet-another-fix-for-estimate_path_cost_size.patch" *** a/contrib/postgres_fdw/postgres_fdw.c --- b/contrib/postgres_fdw/postgres_fdw.c *************** *** 2625,2631 **** estimate_path_cost_size(PlannerInfo *root, * bare scan each time. Instead, use the costs if we have cached them * already. */ ! if (fpinfo->rel_startup_cost > 0 && fpinfo->rel_total_cost > 0) { startup_cost = fpinfo->rel_startup_cost; run_cost = fpinfo->rel_total_cost - fpinfo->rel_startup_cost; --- 2625,2631 ---- * bare scan each time. Instead, use the costs if we have cached them * already. */ ! if (fpinfo->rel_startup_cost >= 0 && fpinfo->rel_total_cost >= 0) { startup_cost = fpinfo->rel_startup_cost; run_cost = fpinfo->rel_total_cost - fpinfo->rel_startup_cost; --------------050400070102040602000708--