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 1rVkDL-00142g-WE for pgsql-hackers@arkaria.postgresql.org; Fri, 02 Feb 2024 03:27:40 +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 1rVkCK-009Pre-SN for pgsql-hackers@arkaria.postgresql.org; Fri, 02 Feb 2024 03:26:36 +0000 Received: from magus.postgresql.org ([2a02:c0:301:0:ffff::29]) by malur.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.94.2) (envelope-from ) id 1rVkCK-009PrV-IR for pgsql-hackers@lists.postgresql.org; Fri, 02 Feb 2024 03:26:36 +0000 Received: from mail-lj1-x234.google.com ([2a00:1450:4864:20::234]) by magus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (Exim 4.94.2) (envelope-from ) id 1rVkCG-0050Vx-PK for pgsql-hackers@postgresql.org; Fri, 02 Feb 2024 03:26:35 +0000 Received: by mail-lj1-x234.google.com with SMTP id 38308e7fff4ca-2cf3ed3b917so19568941fa.1 for ; Thu, 01 Feb 2024 19:26:32 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1706844390; x=1707449190; darn=postgresql.org; h=cc:to:subject:message-id:date:from:in-reply-to:references :mime-version:from:to:cc:subject:date:message-id:reply-to; bh=WUZ4QZzjVbjxG/MjFNsZOLzSLPDuXnT4sta6SgTuruc=; b=KtPMrurJ+SPU+wCigSq1Ul2SPG0A9TxEn5QA+T48ZihP4Rnq2DkfxIWv4ZjQEwUUiC aE4zbsbpt8JKIsKwVyLQLoTyGYI1MZMvp/yAX2gnGjTXk/Xk6flLdDUFcIPpziS0zM9N 8HN+HGt+G5lfUuR3l5Z3f0Q2XmEib3ywxuEnsrjloS+uEd/tCPe+jUilza04ij31C/ZD Rx67se3yU5tjXd7e1l95PD5L8mJ6gT55k8g74SuEHeR6mv8g0Tb/DB09dTTkZ/Lyn7Wm YIjBMbXXS3gW3dWYChhYFZzOYoFRFzY8QqVwt3PTPil53YCJWKFjeZm+yy9lXYZ9LxKc smEw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1706844390; x=1707449190; h=cc:to:subject:message-id:date:from:in-reply-to:references :mime-version:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=WUZ4QZzjVbjxG/MjFNsZOLzSLPDuXnT4sta6SgTuruc=; b=UmNxl8e73DKFo5skWxGeuWL1oRb+dU3FQaZfsD1/xcIoG9z+pPNDhmoDbrXR5y8gts IMK+cADoGzNmZ2Z/cGJXZBwbJy3I3CK4ZI/ykl8RtxHsmuOcXoXutOPQrGczi85iuDn6 A+Afh5WpFcLVQiwqiD6h84MpNSq1L/2iDfK6WQabvP8FwvGthBmCEjOCeqZY8U/DM0Mk st6RQnw/FWCQZIGqosArfd0BR62qK2eu8EVotjg2TuD6mA7GS800HG2YKpWZ9qDXM860 SMsikYl1xnwZrw37NqzijGTI3A5+XdPK4JzrpFS16NNURPgS4WRMaTkSRFetBhYPKmnd UWcg== X-Gm-Message-State: AOJu0YwMIcQhK+zrnZ51aNKlrdHnTrOcWtZVd4XQBB0OswbwWcsXTYrg Y5xnIeKnlD2HhXLlQCeIM7MuVpIpGPxktz3ZGj9Es8OTgIonwtVlkCqtOMcWKSGBQhn3lIiYYLg LoURfnEQjfFGhcnnhir+u0ed9DOc= X-Google-Smtp-Source: AGHT+IFUJe2rOtX52geWD7tVb79vIlYCjJ5p+AtHrnx1rnIJC73o6MqnWyKW5pHTtesodUaNGKUc2AZllONNtlvuI/s= X-Received: by 2002:a05:651c:c93:b0:2d0:6eff:6e03 with SMTP id bz19-20020a05651c0c9300b002d06eff6e03mr4812795ljb.0.1706844390380; Thu, 01 Feb 2024 19:26:30 -0800 (PST) MIME-Version: 1.0 References: In-Reply-To: From: David Rowley Date: Fri, 2 Feb 2024 16:26:18 +1300 Message-ID: Subject: Re: An improvement on parallel DISTINCT To: Richard Guo Cc: PostgreSQL-development Content-Type: text/plain; charset="UTF-8" List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk On Wed, 27 Dec 2023 at 00:23, Richard Guo wrote: > -- on master > EXPLAIN (costs off) > SELECT DISTINCT four FROM tenk1; > QUERY PLAN > ---------------------------------------------------- > Unique > -> Sort > Sort Key: four > -> Gather > Workers Planned: 2 > -> HashAggregate > Group Key: four > -> Parallel Seq Scan on tenk1 > (8 rows) > > -- on patched > EXPLAIN (costs off) > SELECT DISTINCT four FROM tenk1; > QUERY PLAN > ---------------------------------------------------- > Unique > -> Gather Merge > Workers Planned: 2 > -> Sort > Sort Key: four > -> HashAggregate > Group Key: four > -> Parallel Seq Scan on tenk1 > (8 rows) > > I believe the second plan is better. I wonder if this change is worthwhile. The sort is only required at all because the planner opted to HashAggregate in phase1, of which the rows are output unordered. If phase1 was done by Group Aggregate, then no sorting would be needed. The only reason the planner didn't Hash Aggregate for phase2 is because of the order we generate the distinct paths and because of STD_FUZZ_FACTOR. Look at the costs of the above plan: Unique (cost=397.24..397.28 rows=4 width=4) if I enable_sort=0; then I get a cheaper plan: HashAggregate (cost=397.14..397.18 rows=4 width=4) If we add more rows then the cost of sorting will grow faster than the cost of hash aggregate due to the O(N log2 N) part of our sort costing. If I drop the index on tenk1(hundred), I only need to go to the "hundred" column to have it switch to Hash Aggregate on the 2nd phase. This is because the number of distinct groups costs the paths for Group Aggregate and Hash Aggregate more than STD_FUZZ_FACTOR apart. Adjusting the STD_FUZZ_FACTOR with the following means Hash Aggregate is used for both phases. -#define STD_FUZZ_FACTOR 1.01 +#define STD_FUZZ_FACTOR 1.0000001 In light of this, do you still think it's worthwhile making this change? For me, I think all it's going to result in is extra planner work without any performance gains. > Attached is a patch that includes this change and also eliminates the > usage of root->upper_targets[] in the core code. It also makes some > tweaks for the comment. We should fix that. We can consider it independently from the other change you're proposing. David