Received: from malur.postgresql.org ([217.196.149.56]) by arkaria.postgresql.org with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1kX9C9-0000kb-Ih for pgsql-performance@arkaria.postgresql.org; Mon, 26 Oct 2020 20:34:21 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.92) (envelope-from ) id 1kX9C8-0004au-DX for pgsql-performance@arkaria.postgresql.org; Mon, 26 Oct 2020 20:34:20 +0000 Received: from makus.postgresql.org ([2001:4800:3e1:1::229]) by malur.postgresql.org with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1kX9C8-0004an-3H for pgsql-performance@lists.postgresql.org; Mon, 26 Oct 2020 20:34:20 +0000 Received: from mail-io1-xd34.google.com ([2607:f8b0:4864:20::d34]) by makus.postgresql.org with esmtps (TLS1.3:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.92) (envelope-from ) id 1kX9C5-0000Kl-0c for pgsql-performance@lists.postgresql.org; Mon, 26 Oct 2020 20:34:19 +0000 Received: by mail-io1-xd34.google.com with SMTP id k21so11856269ioa.9 for ; Mon, 26 Oct 2020 13:34:16 -0700 (PDT) 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=aKIJoD4Wgi/295MOB4Z2gnX3LHq9V5GdFGkE7KtK7Qw=; b=bXVS2U4fqiJDnPQlLhQG2/iD6RQvTn8myi7dlDLBv5H4Te8EnISQGbBUkpJai3nY6p Ux7gsXXOzbxO6har0eOeZwu1sH0QiChnBzzq/BBTQSwgIXRS0h0OE6Sx4UNeeWUEGPaF rGccjAudUDuOg2bcpJfmJIVtq7vQd3XhhZt9a9nlWmJ71DBzQujEjPzNyOVZztm2t7G+ krvew1tSb+M4mD2+6vfzv+EFpcp/QXe3sNFBcwsT/SsQ9jtq64B9lJCfQkjtmvU+B8sN 2C061se1WXyNlhpN/fPc9PWQE+rFaxM4afIKfjdKo6+awp8flJHW443Klts00K93VJAw /g3Q== 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=aKIJoD4Wgi/295MOB4Z2gnX3LHq9V5GdFGkE7KtK7Qw=; b=fYTVwpRX2gp4WKyMyhs0Z1MYMwzRzPjHMG/WIjeJh4HqDFD/MTh5TjokODM7jK9Auu 6Qf6q0TitjzjnlF3ZYBUCpZgAMcpNTNyj23pmhtT7gKvwIlNBb3b/kZM+JPUBwGAYxu9 iAea0zZrWxjP5Fc742NZZiIaoqqtrxiptdiFLCCABNiefZIk1sPFJ9eLM2Y6aCg9RWhl eNHwLUNr0iQIgw2C/aQEMbd7n64iB2TXjiyObf8hrfl49B1qlrLdSXsXwTJZuMhS6zYg 6bhsPHx2bvFWrw7yLy/QAHdF/5W/EnAS3ECD0i2kh5EcANalILtTItKNFlzBKAbAv8mz j+BQ== X-Gm-Message-State: AOAM531Jc+niT7X28mgKv8yjIk67n8SPNM53nXWpvl1BiAM5caa97CQP iM8xhf+pD0PnCMtiCvOfIhIZ5A== X-Google-Smtp-Source: ABdhPJxyGb6JOZdYaju5GsnK7H0/T2O2cyWPrFg0DxtGWEOBgacAIJfr7OtSmBJ3pYWeBBDosPxwcA== X-Received: by 2002:a02:2206:: with SMTP id o6mr13155522jao.137.1603744455759; Mon, 26 Oct 2020 13:34:15 -0700 (PDT) Received: from pryzbyj.telsasoft (charmander.telsasoft.com. [50.244.222.1]) by smtp.gmail.com with ESMTPSA id g185sm6990440ilh.35.2020.10.26.13.34.14 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Mon, 26 Oct 2020 13:34:15 -0700 (PDT) Received: by pryzbyj.telsasoft (Postfix, from userid 1000) id 7FA2F80090D; Mon, 26 Oct 2020 15:34:13 -0500 (CDT) Date: Mon, 26 Oct 2020 15:34:13 -0500 From: Justin Pryzby To: "Ehrenreich, Sigrid" Cc: pgsql-performance@lists.postgresql.org Subject: Re: Postgres Optimizer ignores information about foreign key relationship, severely misestimating number of returned rows in join Message-ID: <20201026203413.GA9241@telsasoft.com> References: MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.9.4 (2018-02-28) List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Precedence: bulk On Mon, Oct 26, 2020 at 03:58:05PM +0000, Ehrenreich, Sigrid wrote: > Hi Performance Guys, > > I hope you can help me. I am joining two tables, that have a foreign key relationship. So I expect the optimizer to estimate the number of the resulting rows to be the same as the number of the returned rows of one of the tables. But the estimate is way too low. > > I have built a test case, where the problem is easily to be seen. I reproduced the problem on v14dev. Note the different estimates between these: postgres=# explain analyze SELECT * FROM fact INNER JOIN dim USING (low_card,anydata1,anydata2) WHERE fact.low_card=2; Hash Join (cost=161.58..358.85 rows=112 width=12) (actual time=8.707..15.717 rows=3289 loops=1) postgres=# explain analyze SELECT * FROM fact INNER JOIN dim USING (low_card,anydata1,anydata2) WHERE fact.low_card BETWEEN 2 AND 2; Hash Join (cost=324.71..555.61 rows=3289 width=12) (actual time=15.966..23.394 rows=3289 loops=1) I think because low_card has an equality comparison in addition to the equijoin, it's being disqualified from the planner's mechanism to consider FKs in join selectivity. https://doxygen.postgresql.org/costsize_8c_source.html#l05024 I don't know enough about this to help more than that.