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 1hlbQY-0006jr-Cb for pgsql-hackers@arkaria.postgresql.org; Thu, 11 Jul 2019 15:56:10 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.89) (envelope-from ) id 1hlbQX-0002cB-81 for pgsql-hackers@arkaria.postgresql.org; Thu, 11 Jul 2019 15:56:09 +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 1hlbQW-0002c3-SD for pgsql-hackers@lists.postgresql.org; Thu, 11 Jul 2019 15:56:09 +0000 Received: from mail-wm1-x343.google.com ([2a00:1450:4864:20::343]) by makus.postgresql.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA1:256) (Exim 4.89) (envelope-from ) id 1hlbQT-0001hh-VA for pgsql-hackers@postgresql.org; Thu, 11 Jul 2019 15:56:07 +0000 Received: by mail-wm1-x343.google.com with SMTP id g67so2093560wme.1 for ; Thu, 11 Jul 2019 08:56:05 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=2ndquadrant-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=DZdkPc0KnlQlgSx+MwSQBR6tdjFmNAwkEsX1yaZUxrg=; b=lsQg0IfCe/iwUxoJVzhUYZ0wdtTXN84XSOwciugh1XLaP2rAw2q8mG+T2YoGICYqwF Nm7IXaXx+43d+2cPOkEXHYCs78I7u85QnuCrg/2odmVcLUwIkKPVk4F8RJLgCxDwv5Ac ezMikWt7E3NevIvkqakYW55kptjzziVwv+eDZlCVWHF2ClIwllmPsZta/n7OMgd0oyWQ oy4KvZOePudg9yaJKZbjs79kzdEF1Zi5+aKwnNk97ju0Jz8JiWqBKeGLYuADLH93mLX1 nMYrg2yePsqtOnEJDTdBAgTvRFSxtOOgmvbQG/hd++C0KzR1XL1qxdM2HeGEC94InWJz hRYw== 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=DZdkPc0KnlQlgSx+MwSQBR6tdjFmNAwkEsX1yaZUxrg=; b=syC50RpsuEUubOiwKPlu9TDPbizi4A6b8WGThjwRZPCHqklDEa8q2GiWrb34l1jUBl LrQiDD2qIEFV1CG4UCcPLfOUMaMiShtIPbNofE7YTaZHmSevqNrmy9BOSgxVdu3lsLlh Uava00zSN1lp399G7xy64iibZUO/yJYnHJ3DduCFHWYlV8K0v9+0G8Bj2NxWvE6mlHLa c7ksqzODMfF1rX+uzOsMk4fLBu5nmDt891Srx+AxMi8P+fxrlDO0V/2r9TW0EEP7y7rZ 8iXQfr6/34f5ge74ghpF1iP/Q2N4+vhBrQAEWSbfFmMKPW7IfLHNStuC71MMilKgv//z nf8Q== X-Gm-Message-State: APjAAAW4mpAWeX6N/+JtW5TCYKj5HlZdz7eOYyFIK6RonVinT7aCVsbX jjPLW6YfXj7/tpeaLEkWirgV/Pd0XUMnMg== X-Google-Smtp-Source: APXvYqx6/1fiPIk3nQM2iVRg1bcavYzK5GsJqmQM2Hio2UBtbYDJxMPeCLYhifogF+yI1+4mOCszfg== X-Received: by 2002:a05:600c:2111:: with SMTP id u17mr5147111wml.64.1562860564507; Thu, 11 Jul 2019 08:56:04 -0700 (PDT) Received: from localhost (cst-prg-93-170.cust.vodafone.cz. [46.135.93.170]) by smtp.gmail.com with ESMTPSA id p14sm5846929wrx.17.2019.07.11.08.56.03 (version=TLS1_3 cipher=AEAD-AES256-GCM-SHA384 bits=256/256); Thu, 11 Jul 2019 08:56:03 -0700 (PDT) Date: Thu, 11 Jul 2019 17:55:58 +0200 From: Tomas Vondra To: Jeff Davis Cc: pgsql-hackers@postgresql.org Subject: Re: Memory-Bounded Hash Aggregation Message-ID: <20190711155520.zqipi23o3yybx7ym@development> References: <507ac540ec7c20136364b5272acbcd4574aa76ef.camel@j-davis.com> <20190703001753.s5e5cme3ucjgeu6c@development> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii; format=flowed Content-Disposition: inline In-Reply-To: User-Agent: NeoMutt/20180716-1444-295967-dirty List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Precedence: bulk On Wed, Jul 03, 2019 at 07:03:06PM -0700, Jeff Davis wrote: >On Wed, 2019-07-03 at 02:17 +0200, Tomas Vondra wrote: >> What does "partitioned hash strategy" do? It's probably explained in >> one >> of the historical discussions, but I'm not sure which one. I assume >> it >> simply hashes the group keys and uses that to partition the data, and >> then >> passing it to hash aggregate. > >Yes. When spilling, it is cheap to partition on the hash value at the >same time, which dramatically reduces the need to spill multiple times. >Previous discussions: > > >> Unfortunately the second link does not work :-( > >It's supposed to be: > > >https://www.postgresql.org/message-id/CAGTBQpa__-NP7%3DkKwze_enkqw18vodRxKkOmNhxAPzqkruc-8g%40mail.gmail.com > > >> I'm not going to block Approach 1, althought I'd really like to see >> something that helps with array_agg. > >I have a WIP patch that I just posted. It doesn't yet work with >ARRAY_AGG, but I think it can be made to work by evicting the entire >hash table, serializing the transition states, and then later combining >them. > >> Aren't all three approaches a way to "fix" hash aggregate? In any >> case, >> it's certainly reasonable to make incremental changes. The question >> is >> whether "approach 1" is sensible step towards some form of "approach >> 3" > >Disk-based hashing certainly seems like a reasonable algorithm on paper >that has some potential advantages over sorting. It certainly seems >sensible to me that we explore the disk-based hashing strategy first, >and then we would at least know what we are missing (if anything) by >going with the hybrid approach later. > >There's also a fair amount of design space to explore in the hybrid >strategy. That could take a while to converge, especially if we don't >have anything in place to compare against. > Makes sense. I haven't thought about how the hybrid approach would be implemented very much, so I can't quite judge how complicated would it be to extend "approach 1" later. But if you think it's a sensible first step, I trust you. And I certainly agree we need something to compare the other approaches against. >> > * It means we have a hash table and sort running concurrently, each >> > using memory. Andres said this might not be a problem[3], but I'm >> > not convinced that the problem is zero. If you use small work_mem >> > for the write phase of sorting, you'll end up with a lot of runs >> > to >> > merge later and that has some kind of cost. >> > >> >> Why would we need to do both concurrently? I thought we'd empty the >> hash >> table before doing the sort, no? > >So you are saying we spill the tuples into a tuplestore, then feed the >tuplestore through a tuplesort? Seems inefficient, but I guess we can. > I think the question is whether we see this as "emergency fix" (for cases that are misestimated and could/would fail with OOM at runtime), or as something that is meant to make "hash agg" more widely applicable. I personally see it as an emergency fix, in which cases it's perfectly fine if it's not 100% efficient, assuming it kicks in only rarely. Effectively, we're betting on hash agg, and from time to time we lose. But even if we see it as a general optimization technique it does not have to be perfectly efficient, as long as it's properly costed (so the planner only uses it when appropriate). If we have a better solution (in terms of efficiency, code complexity, etc.) then sure - let's use that. But considering we've started this discussion in ~2015 and we still don't have anything, I wouldn't hold my breath. Let's do something good enough, and maybe improve it later. >> Do we actually need to handle that case? How many such aggregates are >> there? I think it's OK to just ignore that case (and keep doing what >> we do >> now), and require serial/deserial functions for anything better. > >Punting on a few cases is fine with me, if the user has a way to fix >it. > +1 to doing that regards -- Tomas Vondra http://www.2ndQuadrant.com PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services