On Sat, Mar 18, 2017 at 6:14 AM, Tom Lane <t...@sss.pgh.pa.us> wrote:
> After a bit more thought, it seems like the bug here is that "the
> fraction of the LHS that has a non-matching row" is not one minus
> "the fraction of the LHS that has a matching row".  In fact, in
> this example, *all* LHS rows have both matching and non-matching
> RHS rows.  So the problem is that neqjoinsel is doing something
> that's entirely insane for semijoin cases.
>
> It would not be too hard to convince me that neqjoinsel should
> simply return 1.0 for any semijoin/antijoin case, perhaps with
> some kind of discount for nullfrac.  Whether or not there's an
> equal row, there's almost always going to be non-equal row(s).
> Maybe we can think of a better implementation but that seems
> like the zero-order approximation.

Right.  If I temporarily hack neqjoinsel() thus:

        result = 1.0 - result;
+
+       if (jointype == JOIN_SEMI)
+               result = 1.0;
+
        PG_RETURN_FLOAT8(result);
 }

... then I obtain sensible row estimates and the following speedups
for TPCH Q21:

  8 workers = 8.3s -> 7.8s
  7 workers = 8.2s -> 7.9s
  6 workers = 8.5s -> 8.2s
  5 workers = 8.9s -> 8.5s
  4 workers = 9.5s -> 9.1s
  3 workers = 39.7s -> 9.9s
  2 workers = 36.9s -> 11.7s
  1 worker  = 38.2s -> 15.0s
  0 workers = 47.9s -> 24.7s

The plan is similar to the good plan from before even at lower worker
counts, but slightly better because the aggregation has been pushed
under the Gather node.  See attached.

-- 
Thomas Munro
http://www.enterprisedb.com
                                                                                
                  QUERY PLAN                                                    
                                               
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
 Limit  (cost=2201513.85..2201514.10 rows=100 width=34) (actual 
time=9063.236..9063.250 rows=100 loops=1)
   ->  Sort  (cost=2201513.85..2201538.56 rows=9882 width=34) (actual 
time=9063.234..9063.242 rows=100 loops=1)
         Sort Key: (count(*)) DESC, supplier.s_name
         Sort Method: top-N heapsort  Memory: 38kB
         ->  Finalize GroupAggregate  (cost=2199767.92..2201136.17 rows=9882 
width=34) (actual time=9041.788..9061.662 rows=3945 loops=1)
               Group Key: supplier.s_name
               ->  Gather Merge  (cost=2199767.92..2200987.95 rows=9880 
width=34) (actual time=9041.743..9059.098 rows=17026 loops=1)
                     Workers Planned: 4
                     Workers Launched: 4
                     ->  Partial GroupAggregate  (cost=2198767.86..2198811.09 
rows=2470 width=34) (actual time=9026.843..9029.020 rows=3405 loops=5)
                           Group Key: supplier.s_name
                           ->  Sort  (cost=2198767.86..2198774.04 rows=2470 
width=26) (actual time=9026.835..9027.507 rows=7781 loops=5)
                                 Sort Key: supplier.s_name
                                 Sort Method: quicksort  Memory: 1067kB
                                 ->  Nested Loop Anti Join  
(cost=558157.24..2198628.67 rows=2470 width=26) (actual time=4200.001..8975.908 
rows=7781 loops=5)
                                       ->  Hash Join  
(cost=558156.67..2143996.29 rows=2470 width=42) (actual time=4198.642..8624.528 
rows=139326 loops=5)
                                             Hash Cond: (l1.l_orderkey = 
orders.o_orderkey)
                                             ->  Nested Loop Semi Join  
(cost=2586.15..1585196.80 rows=199953 width=50) (actual time=14.685..4251.092 
rows=288319 loops=5)
                                                   ->  Hash Join  
(cost=2585.58..1425767.03 rows=199953 width=42) (actual time=14.635..3160.867 
rows=298981 loops=5)
                                                         Hash Cond: 
(l1.l_suppkey = supplier.s_suppkey)
                                                         ->  Parallel Seq Scan 
on lineitem l1  (cost=0.00..1402436.29 rows=4998834 width=16) (actual 
time=0.056..2355.120 rows=7585870 loops=5)
                                                               Filter: 
(l_receiptdate > l_commitdate)
                                                               Rows Removed by 
Filter: 4411341
                                                         ->  Hash  
(cost=2535.58..2535.58 rows=4000 width=30) (actual time=14.470..14.470 
rows=3945 loops=5)
                                                               Buckets: 4096  
Batches: 1  Memory Usage: 279kB
                                                               ->  Nested Loop  
(cost=79.29..2535.58 rows=4000 width=30) (actual time=1.807..13.024 rows=3945 
loops=5)
                                                                     ->  Seq 
Scan on nation  (cost=0.00..1.31 rows=1 width=4) (actual time=0.024..0.031 
rows=1 loops=5)
                                                                           
Filter: (n_name = 'ETHIOPIA'::bpchar)
                                                                           Rows 
Removed by Filter: 24
                                                                     ->  Bitmap 
Heap Scan on supplier  (cost=79.29..2494.27 rows=4000 width=38) (actual 
time=1.776..11.984 rows=3945 loops=5)
                                                                           
Recheck Cond: (s_nationkey = nation.n_nationkey)
                                                                           Heap 
Blocks: exact=1898
                                                                           ->  
Bitmap Index Scan on idx_supplier_nation_key  (cost=0.00..78.29 rows=4000 
width=0) (actual time=1.260..1.260 rows=3945 loops=5)
                                                                                
 Index Cond: (s_nationkey = nation.n_nationkey)
                                                   ->  Index Scan using 
idx_lineitem_orderkey on lineitem l2  (cost=0.56..21.18 rows=159 width=16) 
(actual time=0.003..0.003 rows=1 loops=1494906)
                                                         Index Cond: 
(l_orderkey = l1.l_orderkey)
                                                         Filter: (l_suppkey <> 
l1.l_suppkey)
                                                         Rows Removed by 
Filter: 0
                                             ->  Hash  
(cost=463721.01..463721.01 rows=7347961 width=4) (actual 
time=4140.371..4140.371 rows=7309184 loops=5)
                                                   Buckets: 8388608  Batches: 1 
 Memory Usage: 322500kB
                                                   ->  Seq Scan on orders  
(cost=0.00..463721.01 rows=7347961 width=4) (actual time=0.035..2674.999 
rows=7309184 loops=5)
                                                         Filter: (o_orderstatus 
= 'F'::bpchar)
                                                         Rows Removed by 
Filter: 7690816
                                       ->  Index Scan using 
idx_lineitem_orderkey on lineitem l3  (cost=0.56..21.58 rows=53 width=16) 
(actual time=0.002..0.002 rows=1 loops=696628)
                                             Index Cond: (l_orderkey = 
l1.l_orderkey)
                                             Filter: ((l_receiptdate > 
l_commitdate) AND (l_suppkey <> l1.l_suppkey))
                                             Rows Removed by Filter: 1
 Planning time: 4.914 ms
 Execution time: 9162.742 ms
-- 
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

Reply via email to