Received: from malur.postgresql.org ([217.196.149.56]) by arkaria.postgresql.org with esmtp (Exim 4.72) (envelope-from ) id 1UcdgN-0001oH-NT for pgsql-performance@arkaria.postgresql.org; Wed, 15 May 2013 15:31:59 +0000 Received: from localhost ([127.0.0.1] helo=postgresql.org) by malur.postgresql.org with smtp (Exim 4.72) (envelope-from ) id 1UcdgN-0001XD-7K for pgsql-performance@arkaria.postgresql.org; Wed, 15 May 2013 15:31:59 +0000 Received: from makus.postgresql.org ([2001:4800:7903:4::125]) by malur.postgresql.org with esmtp (Exim 4.72) (envelope-from ) id 1UcdgL-0001V5-8T for pgsql-performance@postgresql.org; Wed, 15 May 2013 15:31:57 +0000 Received: from smtp2.peak6.com ([38.98.137.9]) by makus.postgresql.org with esmtp (Exim 4.72) (envelope-from ) id 1UcdgD-0006Ud-Sa for pgsql-performance@postgresql.org; Wed, 15 May 2013 15:31:55 +0000 X-AuditID: 0a02cb20-b7f886d000007309-83-5193aa6498f0 Received: from sswchi5pcas1.peak6.net (Unknown_Domain [10.100.13.22]) by smtp2.peak6.com (Symantec Messaging Gateway) with SMTP id 31.6C.29449.46AA3915; Wed, 15 May 2013 10:31:48 -0500 (CDT) Received: from [10.10.201.64] (10.10.201.64) by sswchi5pcas1.peak6.net (10.100.13.25) with Microsoft SMTP Server (TLS) id 14.2.247.3; Wed, 15 May 2013 10:31:48 -0500 Message-ID: <5193AA62.2040700@optionshouse.com> Date: Wed, 15 May 2013 10:31:46 -0500 From: Shaun Thomas Reply-To: Organization: Peak6 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:17.0) Gecko/20130329 Thunderbird/17.0.5 MIME-Version: 1.0 To: "pgsql-performance@postgresql.org" Subject: Thinking About Correlated Columns (again) Content-Type: text/plain; charset="ISO-8859-1"; format=flowed content-transfer-encoding: 7bit X-Originating-IP: [10.10.201.64] X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFnrEIsWRmVeSWpSXmKPExsXClcIrppuyanKgweOLGhbXZ55jdmD0uLBv GnsAY1QDo01iXl5+SWJJqkJKanGyrZJ/QUlmfl6xR35pcaqCS2Zxck5iZm5qkZJCZoqtkrGS QkFOYnJqbmpeia1SYkFBal6Kkh2XAgawASrLzFNIzUvOT8nMS7dV8gz217WwMLXUNVSyi0cG CZ0sGWdnn2cq+CxY8f7dOuYGxj+8XYycHBICJhJz3m9igbDFJC7cW8/WxcjFISRwgFHiz6te dghnJaPE9kXbGEGqeAX0JZb9PMgOYrMIqEr8uzADLM4moCsxqX8FG4gtJKAi0Xf2BhOIzS8g LLHvQxMziC0qECaxav0yZog5ghInZz4B2ywi4Ckxe/82MFtYwEji76mpYL3MArYSF+ZcZ4Gw 5SW2v53DDDFfVWJF80Q2iKsVJP5fecc0gVFwFpKxs5C0z0LSvoCReRWjeHFZYnJGpllBcW5J gZFeQWpitpleXmrJJkZQRDKdVtjBuLnH6hCjAAejEg/vh0WTA4VYE8uKK3MPMUpwMCuJ8N5Y BhTiTUmsrEotyo8vKs1JLT7E6AMMj4nMUqLJ+cBkkVcSb2hsamBqaWpoam5qaIRDWEmcd9al pkAhgXRg2shOTS1ILYIZx8TBKdXAaJfD/OT3SumqTXvaym9a7fS+nZpyo77g61NzkbArrF48 z+aLLGVQUn+54sND9wU3ygx2rbknlPXnsdCWDQ9CV31w4HC99Hfxri0pTz8G//NS3Km64A6z 8V/16tDOLUFbkh/PKgx2kNz9WHz67/KQUzv/mzKE5z/4+nm53MwfE3w3xc7k61dYUaTEUpyR aKjFXFScCAApxN9w9QIAAA== X-Pg-Spam-Score: 0.8 (/) 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 Hi! This has been a pain point for quite a while. While we've had several discussions in the area, it always seems to just kinda trail off and eventually vanish every time it comes up. A really basic example of how bad the planner is here: CREATE TABLE foo AS SELECT a.id, a.id % 1000 AS col_a, a.id % 1000 AS col_b FROM generate_series(1, 1000000) a(id); CREATE INDEX idx_foo_ab ON foo (col_a, col_b); ANALYZE foo; EXPLAIN ANALYZE SELECT * FROM foo WHERE col_a = 50 AND col_b = 50; Index Scan using idx_foo_ab on foo (cost=0.00..6.35 rows=1 width=12) (actual time=0.030..3.643 rows=1000 loops=1) Index Cond: ((col_a = 50) AND (col_b = 50)) Hey, look! The row estimate is off by a factor of 1000. This particular case doesn't suffer terribly from the mis-estimation, but others do. Boy, do they ever. Since there really is no fix for this aside from completely rewriting the query or horribly misusing CTEs (to force sequence scans instead of bloated nested loops, for example), I recently tried to use some existing ALTER TABLE syntax: ALTER TABLE foo ALTER col_a SET (n_distinct = 1); ALTER TABLE foo ALTER col_b SET (n_distinct = 1); The new explain output: Index Scan using idx_foo_ab on foo (cost=0.00..9.37 rows=2 width=12) (actual time=0.013..0.871 rows=1000 loops=1) Index Cond: ((col_a = 50) AND (col_b = 50)) Well... 2 is closer to 1000 than 1 was, but it's pretty clear the histogram is still the basis for the cost estimates. I'm curious what benefit overriding the n_distinct pg_stats field actually gives us in practice. I'm worried that without an easy answer for cases like this, more DBAs will abuse optimization fences to get what they want and we'll end up in a scenario that's actually worse than query hints. Theoretically, query hints can be deprecated or have GUCs to remove their influence, but CTEs are forever, or until the next code refactor. I've seen conversations on this since at least 2005. There were even proposed patches every once in a while, but never any consensus. Anyone care to comment? -- Shaun Thomas OptionsHouse | 141 W. Jackson Blvd. | Suite 500 | Chicago IL, 60604 312-676-8870 sthomas@optionshouse.com ______________________________________________ See http://www.peak6.com/email_disclaimer/ for terms and conditions related to this email -- Sent via pgsql-performance mailing list (pgsql-performance@postgresql.org) To make changes to your subscription: http://www.postgresql.org/mailpref/pgsql-performance