Received: from malur.postgresql.org ([2a02:16a8:dc51::56]) by arkaria.postgresql.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA384:256) (Exim 4.89) (envelope-from ) id 1fO6Mt-0003VT-40 for pgsql-performance@arkaria.postgresql.org; Wed, 30 May 2018 19:02:43 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.89) (envelope-from ) id 1fO6Mr-0002GY-Il for pgsql-performance@arkaria.postgresql.org; Wed, 30 May 2018 19:02:41 +0000 Received: from makus.postgresql.org ([2001:4800:1501:1::229]) by malur.postgresql.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA384:256) (Exim 4.89) (envelope-from ) id 1fO6Mr-0002GO-2j for pgsql-performance@lists.postgresql.org; Wed, 30 May 2018 19:02:41 +0000 Received: from mail-io0-x241.google.com ([2607:f8b0:4001:c06::241]) by makus.postgresql.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA1:256) (Exim 4.89) (envelope-from ) id 1fO6Mn-0006a0-15 for pgsql-performance@postgresql.org; Wed, 30 May 2018 19:02:39 +0000 Received: by mail-io0-x241.google.com with SMTP id a10-v6so22895718ioc.9 for ; Wed, 30 May 2018 12:02:36 -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=c5w7jkPh7bDWX+WDfRBNy9nkhUn8/WSsbpXsgefFC+0=; b=WaKGx5BxNWt6bN+OnztcjvyJlXkTquo5jHLwseaexcpAWY6/jqu5ncO1oQNK07h5mQ zEn8jiCaLM50cbl2oITOMr7y/1DdjY33YMJqq1JcN+0iyr082p63tRd2vYzGXu5pajGL vCZvfljJObmLNmOueyebIKE/PTf2RTArCToNO87nn1FghGI57CHu1u2juR5GnfaIMntM UatNQ+pOLHE0xTsJdd3nNrj0sAU/3xuKJ3RBlFPHsv1G4jlfhHocuqIj/7H8Qx5GfVOY p+5ohC3CBS0AdHQgLAFER8OreVJcnmUDBj1hXfVwDkjfhh+LmPuK/4enw0kjsuPgSFpz qHIQ== 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=c5w7jkPh7bDWX+WDfRBNy9nkhUn8/WSsbpXsgefFC+0=; b=p7TSd6aYtsE919mHYUDlv6P+vQQISEP2aBCMhG8SUzf8sOaNPt+nYzYPII3qIV8eAD rM/9pLz0YGSyxa05mB0smWdAb+M9FsYOCMQtqvo0cQG/1xs4qUgLu+452xr1+NAQTLDi 3atSpRaqlhdy8eUM59bF8Lmm7+mxSPTmacV6ASDC9uDi6LFTs4HR7vAIj1mbN562nD4c DEcfmEVPlyHxo0lUokcyZVtOwS+BRovsBfPQaNaX36UKlZdC9r/oPXzosh9LSlchBCSH zkkX/uICqaXjr7MVkv8Lw868hisjb2xMRfQRbkx+GyNaJFR5I4nAIJLNmBX+Mt4MK29a YhMQ== X-Gm-Message-State: APt69E1CKA2eXYJdp141678nU0csqP/bSsd8dfY1wsE36pTO0dlrNc9i PG42w2modwNue+60kVRoYU+qK2QlBTU= X-Google-Smtp-Source: ADUXVKIWNtM5J3IKOLw/BJWxnt0kjS0trw5m8gGYso218XXN8rUjy5EIT/KUH0BUGSSmVM58LBI8Wg== X-Received: by 2002:a6b:2251:: with SMTP id i78-v6mr3193948ioi.276.1527706952945; Wed, 30 May 2018 12:02:32 -0700 (PDT) Received: from pryzbyj (charmander.telsasoft.com. [50.244.222.1]) by smtp.gmail.com with ESMTPSA id m137-v6sm8664347itg.14.2018.05.30.12.02.32 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 30 May 2018 12:02:32 -0700 (PDT) Received: by pryzbyj (Postfix, from userid 1000) id 5675B80186B; Wed, 30 May 2018 14:02:31 -0500 (CDT) Date: Wed, 30 May 2018 14:02:31 -0500 From: Justin Pryzby To: Christopher Wilson Cc: "pgsql-performance@postgresql.org" , Steven Winfield Subject: Re: Possible optimisation: push down SORT and LIMIT nodes Message-ID: <20180530190231.GH5164@telsasoft.com> References: MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.5.23 (2014-03-12) List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Precedence: bulk On Wed, May 30, 2018 at 03:46:40PM +0000, Christopher Wilson wrote: > We have a query which is rather slow (about 10 seconds), and it looks like this: > > The inventory table has the quantity of each asset in the inventory on each > date (complete SQL to create and populate the tables with dummy data is > below). The query plan looks like this (the non-parallel version is similar): Hi, Thanks for including the test case. > Limit (cost=217591.77..217603.60 rows=100 width=32) (actual time=9122.235..9122.535 rows=100 loops=1) ... > -> Sort (cost=216591.73..220628.83 rows=1614839 width=32) (actual time=8879.909..8880.030 rows=727 loops=4) > Sort Key: inventory.date, asset.name > Sort Method: external merge Disk: 50904kB > Buffers: shared hit=27365, temp read=25943 written=25947 Yep, the sort is expensive and largely wasted.. > I'm imagining something like a sort-limit-finish node, which sorts its input > and then returns at least the limit number of rows, but keeps returning rows > until it exhausts the last sort prefix that it read. [...] > Does this sound correct, reasonable and potentially interesting to Postgres > developers? I think your analysis may be (?) unecessarily specific to your specific problem query. For diagnostic purposes, I was able to to vastly improve the query runtime with a CTE (WITH): |postgres=# explain(analyze,buffers) WITH x AS (SELECT inventory.date, asset.name, inventory.quantity FROM temp.inventory LEFT JOIN temp.asset ON asset.id=id_asset LIMIT 99) SELECT * FROM x ORDER BY date, name; | Sort (cost=1090.60..1090.85 rows=99 width=40) (actual time=3.764..3.988 rows=99 loops=1) | Sort Key: x.date, x.name | Sort Method: quicksort Memory: 32kB | Buffers: shared hit=298 | CTE x | -> Limit (cost=0.28..889.32 rows=99 width=31) (actual time=0.063..2.385 rows=99 loops=1) | Buffers: shared hit=298 | -> Nested Loop Left Join (cost=0.28..44955006.99 rows=5006001 width=31) (actual time=0.058..1.940 rows=99 loops=1) | Buffers: shared hit=298 | -> Seq Scan on inventory (cost=0.00..5033061.00 rows=5006001 width=12) (actual time=0.020..0.275 rows=99 loops=1) | Buffers: shared hit=1 | -> Index Scan using asset_pkey on asset (cost=0.28..7.98 rows=1 width=27) (actual time=0.008..0.008 rows=1 loops=99) | Index Cond: (id = inventory.id_asset) | Buffers: shared hit=297 | -> CTE Scan on x (cost=0.00..198.00 rows=99 width=40) (actual time=0.073..2.989 rows=99 loops=1) | Buffers: shared hit=298 | Planning time: 0.327 ms | Execution time: 4.260 ms It's not clear to me if there's some reason why the planner couldn't know to use a similar plan (sort-limit-... rather than limit-sort-...) Justin