Received: from malur.postgresql.org ([217.196.149.56]) by arkaria.postgresql.org with esmtp (Exim 4.84_2) (envelope-from ) id 1eH6Pe-0000cG-Rd for pgsql-performance@arkaria.postgresql.org; Tue, 21 Nov 2017 11:08:23 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.84_2) (envelope-from ) id 1eH6Pe-00029U-Bt for pgsql-performance@arkaria.postgresql.org; Tue, 21 Nov 2017 11:08:22 +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 1eH6Lr-0001lx-1u for pgsql-performance@lists.postgresql.org; Tue, 21 Nov 2017 11:04:27 +0000 Received: from out4-smtp.messagingengine.com ([66.111.4.28]) by magus.postgresql.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA384:256) (Exim 4.89) (envelope-from ) id 1eH6Lj-00038b-2F for pgsql-performance@postgresql.org; Tue, 21 Nov 2017 11:04:26 +0000 Received: from compute3.internal (compute3.nyi.internal [10.202.2.43]) by mailout.nyi.internal (Postfix) with ESMTP id C3CFE21092 for ; Tue, 21 Nov 2017 06:04:17 -0500 (EST) Received: from web1 ([10.202.2.211]) by compute3.internal (MEProxy); Tue, 21 Nov 2017 06:04:17 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=zvs.no; h= content-transfer-encoding:content-type:date:from:message-id :mime-version:subject:to:x-me-sender:x-me-sender:x-sasl-enc; s= mesmtp; bh=71JDSPROpKr+LsvNnDNolIL7JrCnRyO6sh3kJqG403k=; b=RqiyY LWCdwM5881g8mw2xhbYNtW5HX/TKo2aqP43qHCUaZ/oM53hzrTJKDTHH69bOvQ3H ypAmY35+pbrCSgTNCtuuSTvVFvcMFiXjajFERRln+nAweo96wA7QpgRoY37kqmcT DdEdjJDmClFVrBq8d5oTvtZl4Mr39Q73byo6J8= DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=content-transfer-encoding:content-type :date:from:message-id:mime-version:subject:to:x-me-sender :x-me-sender:x-sasl-enc; s=fm1; bh=71JDSPROpKr+LsvNnDNolIL7JrCnR yO6sh3kJqG403k=; b=NVpVsfG1QRnDj8qfMI275JwyGN3M+UfSEspLe+o0wzUzD nuxslLi0//xJnMRuur3q2vbtXv78OshF2SEGZuy05Jf9EOv4gdLHV0ikTeN1nWFE UkTDiFDDprGiPdDlEQVYj0WyNJSszh3n6LghUXMGp2TL5bi2lNtjUtRJC1WlTVy9 cwVYhaS1ycTwGPY5RXAI4ZbM2c/SMKlkRsVATs0SPORIeU5TsU8UpGs8aAnLfIDQ gIsNLrgDjRS917yOlhUDtv1zRDnRpV9fa4QDZy1kMqb2KPtkNEROVMYEpbWVg3Bo AAWYW8WKh3e96w0b0JBMSuKJMqv/M6WA/QsykgU0w== X-ME-Sender: Received: by mailuser.nyi.internal (Postfix, from userid 99) id 9AC0F957A1; Tue, 21 Nov 2017 06:04:17 -0500 (EST) Message-Id: <1511262257.3219920.1179611992.260EC9D9@webmail.messagingengine.com> From: Zakhar Shapurau To: pgsql-performance@postgresql.org MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Content-Type: text/plain; charset="utf-8" X-Mailer: MessagingEngine.com Webmail Interface - ajax-a169161c Subject: Using GROUPING SETS with more than one set disables predicate pushdown? Date: Tue, 21 Nov 2017 12:04:17 +0100 List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Precedence: bulk Hi! First of all, thanks for the great work! PostgreSQL is amazing, and community is super helpful. I found an unexpected behaviour in PostgreSQL, and was advised to post it to the performance mailing list on IRC. Using GROUPING SETS with more than one set disables predicate pushdown? Version: PostgreSQL 9.6.6 on x86_64-pc-linux-gnu, compiled by gcc (Ubuntu 5.4.0-6ubuntu1~16.04.4) 5.4.0 20160609, 64-bit Seems like when GROUPING SETS with at least two sets are used in the subquery, planner can not push WHERE clauses inside. Here are two queries that (I think) are equivalent, but produce very different execution plans leading to bad performance on real data - and in effect, making it impossible to abstract away non-trivial grouping logic into a view. It might as well be that queries are not really equivalent, but I don't see how. Same problem happens even if grouping sets are the same - like `GROUPING SETS ((), ())`. CREATE TEMPORARY TABLE test_gs ( x INT, y INT, z INT, PRIMARY KEY (x, y, z) ); EXPLAIN SELECT x, y, avg(z) AS mean FROM test_gs WHERE x = 1 GROUP BY x, GROUPING SETS ((y), ()); QUERY PLAN ----------------------------------------------------------------------------------------- GroupAggregate (cost=0.15..8.65 rows=20 width=40) Group Key: x, y Group Key: x -> Index Only Scan using test_gs_pkey on test_gs (cost=0.15..8.33 rows=10 width=12) Index Cond: (x = 1) (5 rows) EXPLAIN SELECT x, y, mean FROM ( SELECT x, y, avg(z) AS mean FROM test_gs GROUP BY x, GROUPING SETS ((y), ()) ) AS g WHERE x = 1; QUERY PLAN -------------------------------------------------------------------------------------------- GroupAggregate (cost=0.15..62.10 rows=404 width=40) Group Key: test_gs.x, test_gs.y Group Key: test_gs.x Filter: (test_gs.x = 1) -> Index Only Scan using test_gs_pkey on test_gs (cost=0.15..41.75 rows=2040 width=12) (5 rows) The issue here is that the second query is not using index to filter on x = 1 , instead it reads all the tuples from an index and applies the filter. Here is also a description in gist: https://gist.github.com/zeveshe/cf92c9d2a6b14518af3180113e767ae7 Thanks a lot! -- Zakhar Shapurau zak@zvs.no +47 407 54 397