dum query plan: more info. - Mailing list pgsql-performance

From Jonathan Moore
Subject dum query plan: more info.
Date
Msg-id 1050530569.20873.120.camel@spunge-bob
Whole thread Raw
Responses Re: dum query plan: more info.
Re: dum query plan: more info.
List pgsql-performance
I now under stand that my join was rong but none of the seguestions are
the optimal solution to the problime. You can make this order n if you
try. The trick is to use a mearg join using sorted list of the unique
keys in each colum join. The question you are asking is what left hand
entrys do not exist on the right.

select A.left form pairs A, pairs B where A.left != B.right;

(note: my code in the first example select left form the rong table but
it dosn't change the search.)

take the DB:

(1,2)
(2,1)
(1,5)
(4,5)
(5,2)

Sort the colums:
left   right
====   =====
 1      1
 2      2
 4      5
 5

Start at the top you see that you have 1 in both columes there for you
know that 1 is not a answer. pop both colums. same for 2. Whe you get to
the top of the lists as 4, 5; you know that 4 apperas on the only in the
left colum as you don't see it on the right. pop the left colum. now you
see that 5 is on both sides so 5 is not a canadate. You are out of
options so you are done 4 is the only value that is on the left and only
on the left.

This methoud is order O(n) if both colums have b-tree indexes so you
don't have to pre sort them othere wise it is O(n*log(n)) as the sort is
the greatest complexity. In eathere case it is way better then O(n^2)
for almost any n.

I have this implmented in my code by selecting each colum and then doing
the mearg my self more expensive then a in db join as there is pointless
data copys.

sudo perl for the hole thing is:

#!/usr/bin/not-realy-perl

my @left = select distinct left_entry from entry_pairs order by
left_entry;

my @right = select distinct right_entry from entry_pairs order by
right_entry;

my @only_left;

while (1) {
  if (not @left) {
    last; #done
  }

  elsif (not @right) {
    push @only_left, $left[0];
    pop @left;
  }

  elsif ($left[0] == $right[0]) {
    pop @left;
    pop @right;
  }

  elsif ($left[0] < $right[0]) {
    push @only_left, $left[0];
    pop @left;
  }

  elsif ($left[0] > $right[0]) {
    pop @right;
  }
}



-Jonathan


pgsql-performance by date:

Previous
From: Jean-Luc Lachance
Date:
Subject: Re: dum query plan
Next
From: Manfred Koizar
Date:
Subject: Re: dum query plan: more info.