Received: from malur.postgresql.org ([217.196.149.56]) by arkaria.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.94.2) (envelope-from ) id 1qyxGk-00CJ6J-Px for pgsql-hackers@arkaria.postgresql.org; Fri, 03 Nov 2023 16:43:38 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.94.2) (envelope-from ) id 1qyxGj-001oyL-CO for pgsql-hackers@arkaria.postgresql.org; Fri, 03 Nov 2023 16:43:37 +0000 Received: from makus.postgresql.org ([2001:4800:3e1:1::229]) by malur.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.94.2) (envelope-from ) id 1qyxGj-001oyC-1c for pgsql-hackers@lists.postgresql.org; Fri, 03 Nov 2023 16:43:37 +0000 Received: from mail-ed1-x52e.google.com ([2a00:1450:4864:20::52e]) by makus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (Exim 4.94.2) (envelope-from ) id 1qyxGd-003nA1-AQ for pgsql-hackers@postgresql.org; Fri, 03 Nov 2023 16:43:35 +0000 Received: by mail-ed1-x52e.google.com with SMTP id 4fb4d7f45d1cf-5441305cbd1so1660512a12.2 for ; Fri, 03 Nov 2023 09:43:31 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=enterprisedb.com; s=google; t=1699029808; x=1699634608; darn=postgresql.org; h=content-transfer-encoding:in-reply-to:from:references:cc:to :content-language:subject:user-agent:mime-version:date:message-id :from:to:cc:subject:date:message-id:reply-to; bh=3K29kW0fM4TWHE+lAUBUgCTWfkKLPlwTj6a85hhOIf0=; b=lGlJEoOXe50AhGuSgyGlHSK3Eb4PuqQp7G5s8xhkwqwmWHpk9hKK+4k4qMH0R6JHsP AwkY2utbBupeADYDyGxiD94i6kZ00nb/72tSP2t789/EqrRdbetLiI1ghGWF0RC+svuu qbm2A2+P1EHagtDlXto6FIIMST8BdFw324V4HvX+Vebl68cQFcM2VqVrHZR1vVAjK4bw J9lo6m0NbdQbeB2EUo0WM86BU1gyt2X+IT5FsdQ1DEu4No8Lve4iU8Dj8iNdGNq5Wuxn jnU659FXzRUfX2z9EBWvSGDzPuYWeIrcMHMBhg4iGPyj+bJkxWRKd+07mKpoL/82wX9G TJrQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1699029808; x=1699634608; h=content-transfer-encoding:in-reply-to:from:references:cc:to :content-language:subject:user-agent:mime-version:date:message-id :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=3K29kW0fM4TWHE+lAUBUgCTWfkKLPlwTj6a85hhOIf0=; b=o20YE+jJ6rai1KVSBqOlxSkB7XnK8BamID9PRzYYXJi4okX9PvMRUWtx5eH6CLvZrk /FStGzPnuRIyG0tomKd0HhiY0oEbP4eiRXtiIpgM0FLhcGH8dl1MrVOufQUo0vaUW2NY q0RF1BrwZFBZefjOo2N6/ElppM54m+SNkBzbG4wH6WTLNXrLRyd2163MqdA+2LLwGdRG F7kKu1FUVMxufh8PtAekwLMNu9YA3REBjQlVLQaLjIj7v8dhI07QHSQL9a5qi/PhkikO cFWyddqIUNAHJLGNRYOdh9vJ+4N+2F9Sg8ngOP+7TkhDonlAa7H2vFduLZoXKzI6RjLf Ie4Q== X-Gm-Message-State: AOJu0Yx119qdm7W16s+Icavf6L6ZVTX3ZB8bk5dmvccxiCU67c8VFXaW MDT/ge4Bn5pt4kBonkmFhBQMbg== X-Google-Smtp-Source: AGHT+IHCVH95UwuSyQYHug6TtiMP7s8KUa8US7QJvg4ysEFVTTCqgvK2QvsQ799YQyqlKqpbZ6SrAA== X-Received: by 2002:a50:8a96:0:b0:544:1fb7:d5e4 with SMTP id j22-20020a508a96000000b005441fb7d5e4mr1841266edj.0.1699029808512; Fri, 03 Nov 2023 09:43:28 -0700 (PDT) Received: from [10.137.0.17] (srv1.mobissw.com. [89.235.0.226]) by smtp.gmail.com with ESMTPSA id f29-20020a50a6dd000000b0053dff5568acsm1150002edc.58.2023.11.03.09.43.27 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Fri, 03 Nov 2023 09:43:28 -0700 (PDT) Message-ID: <1de52b5f-e4a6-5729-eeef-51d524534665@enterprisedb.com> Date: Fri, 3 Nov 2023 17:43:26 +0100 MIME-Version: 1.0 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:102.0) Gecko/20100101 Thunderbird/102.15.1 Subject: Re: MergeJoin beats HashJoin in the case of multiple hash clauses Content-Language: en-US To: Lepikhov Andrei , Andy Fan Cc: PostgreSQL-development , Tom Lane References: <52257607-57f6-850d-399a-ec33a654457b@postgrespro.ru> <84114cba-97e9-49f8-952f-04cf321125c1@app.fastmail.com> From: Tomas Vondra In-Reply-To: <84114cba-97e9-49f8-952f-04cf321125c1@app.fastmail.com> Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk On 9/11/23 10:04, Lepikhov Andrei wrote: > > > On Mon, Sep 11, 2023, at 11:51 AM, Andy Fan wrote: >> Hi, >> >> On Thu, Jun 15, 2023 at 4:30 PM Andrey Lepikhov >> wrote: >>> Hi, all. >>> >>> Some of my clients use JOIN's with three - four clauses. Quite >>> frequently, I see complaints on unreasonable switch of JOIN algorithm to >>> Merge Join instead of Hash Join. Quick research have shown one weak >>> place - estimation of an average bucket size in final_cost_hashjoin (see >>> q2.sql in attachment) with very conservative strategy. >>> Unlike estimation of groups, here we use smallest ndistinct value across >>> all buckets instead of multiplying them (or trying to make multivariate >>> analysis). >>> It works fine for the case of one clause. But if we have many clauses, >>> and if each has high value of ndistinct, we will overestimate average >>> size of a bucket and, as a result, prefer to use Merge Join. As the >>> example in attachment shows, it leads to worse plan than possible, >>> sometimes drastically worse. >>> I assume, this is done with fear of functional dependencies between hash >>> clause components. But as for me, here we should go the same way, as >>> estimation of groups. >> Yes, this analysis is correct - final_cost_hashjoin assumes the clauses may be correlated (not necessarily by functional dependencies, just that the overall ndistinct is not a simple product of per-column ndistincts). And it even says so in the comment before calculating bucket size: * Determine bucketsize fraction and MCV frequency for the inner * relation. We use the smallest bucketsize or MCV frequency estimated * for any individual hashclause; this is undoubtedly conservative. I'm sure this may lead to inflated cost for "good" cases (where the actual bucket size really is a product), which may push the optimizer to use the less efficient/slower join method. Unfortunately, AFAICS the patch simply assumes the extreme in the opposite direction - it assumes each clause splits the bucket for each distinct value in the column. Which works great when it's true, but surely it'd have issues when the columns are correlated? I think this deserves more discussion, i.e. what happens if the assumptions do not hold? We know what happens for the conservative approach, but what's the worst thing that would happen for the optimistic one? I doubt e can simply switch from the conservative approach to the optimistic one. Yes, it'll make some queries faster, but for other queries it likely causes problems and slowdowns. IMHO the only principled way forward is to get a better ndistinct estimate (which this implicitly does), perhaps by using extended statistics. I haven't tried, but I guess it'd need to extract the clauses for the inner side, and call estimate_num_groups() on it. This however reminds me we don't use extended statistics for join clauses at all. Which means that even with accurate extended statistics, we can still get stuff like this for multiple join clauses: Hash Join (cost=1317.00..2386.00 rows=200 width=24) (actual time=85.781..8574.784 rows=8000000 loops=1) This is unrelated to the issue discussed here, of course, as it won't affect join method selection for that join. But it certainly will affect all estimates/costs above that join, which can be pretty disastrous. regards -- Tomas Vondra EnterpriseDB: http://www.enterprisedb.com The Enterprise PostgreSQL Company