Received: from malur.postgresql.org ([217.196.149.56]) by arkaria.postgresql.org with esmtp (Exim 4.84_2) (envelope-from ) id 1dzUYi-0004hH-1l for pgsql-performance@arkaria.postgresql.org; Tue, 03 Oct 2017 21:16:56 +0000 Received: from localhost ([127.0.0.1] helo=postgresql.org) by malur.postgresql.org with smtp (Exim 4.84_2) (envelope-from ) id 1dzUYh-0004ox-8G for pgsql-performance@arkaria.postgresql.org; Tue, 03 Oct 2017 21:16:55 +0000 Received: from magus.postgresql.org ([2a02:c0:301:0:ffff::29]) by malur.postgresql.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA384:256) (Exim 4.84_2) (envelope-from ) id 1dzUYg-0004om-Dp for pgsql-performance@postgresql.org; Tue, 03 Oct 2017 21:16:54 +0000 Received: from cat-porwal-prod-mail1.catalyst.net.nz ([2404:130:4080::4]) by magus.postgresql.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA384:256) (Exim 4.84_2) (envelope-from ) id 1dzUYY-0000Lh-Ia for pgsql-performance@postgresql.org; Tue, 03 Oct 2017 21:16:52 +0000 Received: from localhost (localhost [127.0.0.1]) by cat-porwal-prod-mail1.catalyst.net.nz (Postfix) with ESMTP id C6A2E80C52; Wed, 4 Oct 2017 10:16:38 +1300 (NZDT) X-Virus-Scanned: Debian amavisd-new at cat-porwal-prod-mail1.servers.catalyst.net.nz Received: from cat-porwal-prod-mail1.catalyst.net.nz ([127.0.0.1]) by localhost (cat-porwal-prod-mail1.servers.catalyst.net.nz [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id BsbdLbPbXSuF; Wed, 4 Oct 2017 10:16:37 +1300 (NZDT) Received: from [IPv6:2406:e001:b54:1:5df7:1ac3:b3d8:2335] (unknown [IPv6:2406:e001:b54:1:5df7:1ac3:b3d8:2335]) (Authenticated sender: mark.kirkwood@catalyst.net.nz) by cat-porwal-prod-mail1.catalyst.net.nz (Postfix) with ESMTPSA id 8764780BA1; Wed, 4 Oct 2017 10:16:37 +1300 (NZDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=catalyst.net.nz; s=catalyst; t=1507065397; bh=piybLMkNtUbz6jPxrWYtnIV69oHj8uaQJQigWdifIPA=; h=Subject:To:Cc:References:From:Date:In-Reply-To; b=DNQYm4mRQEUOU6zVbag8bWhQ0SwTQlsSnUWDWEJLAIEyRYs5Wi4uArGy30QbnOagQ nNL3ngM6luu4VR9c/b4wRmpuCbQ8kSlFE6pxDLGJrxbeVwz5JRheR9HxKrh7hWvF3V /H8eYNV8wRA7ycCTFBgGxV7jqbezPEQ3aYz8SY1I= Subject: Re: select with max functions To: Tom Lane , Mariel Cherkassky Cc: Gerardo Herzig , pgsql-performance@postgresql.org References: <0970df65-602e-724d-2c39-e4695ae48bb6@a-kretschmer.de> <1990398729.67887.1506951911360.JavaMail.zimbra@fmed.uba.ar> <16484.1506958199@sss.pgh.pa.us> From: Mark Kirkwood Message-ID: <002ad4b4-ec5f-4e9f-fa48-5c19405292ee@catalyst.net.nz> Date: Wed, 4 Oct 2017 10:16:37 +1300 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:52.0) Gecko/20100101 Thunderbird/52.3.0 MIME-Version: 1.0 In-Reply-To: <16484.1506958199@sss.pgh.pa.us> Content-Type: text/plain; charset=utf-8; format=flowed Content-Transfer-Encoding: 8bit Content-Language: en-US List-Archive: List-Help: List-ID: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: X-Mailing-List: pgsql-performance Precedence: bulk Sender: pgsql-performance-owner@postgresql.org On 03/10/17 04:29, Tom Lane wrote: > Mariel Cherkassky writes: >> explain analyze SELECT Ma.User_Id, >> COUNT(*) COUNT >> FROM Manuim Ma >> WHERE Ma.Bb_Open_Date = >> (SELECT Bb_Open_Date >> FROM Manuim Man >> WHERE Man.User_Id = Ma.User_Id order >> by bb_open_date desc limit 1 >> ) >> GROUP BY Ma.User_Id >> HAVING COUNT(*) > 1; > The core problem with this query is that the sub-select has to be done > over again for each row of the outer table, since it's a correlated > sub-select (ie, it refers to Ma.User_Id from the outer table). Replacing > a max() call with handmade logic doesn't do anything to help that. > I'd try refactoring it so that you calculate the max Bb_Open_Date just > once for each user id, perhaps along the lines of > > SELECT Ma.User_Id, > COUNT(*) COUNT > FROM Manuim Ma, > (SELECT User_Id, max(Bb_Open_Date) as max > FROM Manuim Man > GROUP BY User_Id) ss > WHERE Ma.User_Id = ss.User_Id AND > Ma.Bb_Open_Date = ss.max > GROUP BY Ma.User_Id > HAVING COUNT(*) > 1; > > This is still not going to be instantaneous, but it might be better. > > It's possible that an index on (User_Id, Bb_Open_Date) would help, > but I'm not sure. > > regards, tom lane > > Further ideas based on Tom's rewrite: If that MAX is still expensive it might be worth breaking SELECT User_Id, max(Bb_Open_Date) as max FROM Manuim Man GROUP BY User_Id out into a VIEW, and considering making it MATERIALIZED, or creating an equivalent  trigger based summary table (there are examples in the docs of how to do this). Cheers Mark -- Sent via pgsql-performance mailing list (pgsql-performance@postgresql.org) To make changes to your subscription: http://www.postgresql.org/mailpref/pgsql-performance