Thread: dum query plan
I am wondering why it uses the O(n^2) nested loop when there is a O(N) methoud using btree indexes for a merg join. I am using 7.2.1 would upgrading fix my problime or is it somthing else? Given the schema: drop table Entry_Pairs; create table Entry_Pairs ( left_entry int REFERENCES Entry ON DELETE RESTRICT, right_entry int REFERENCES Entry ON DELETE RESTRICT, relation int NOT NULL , subtract bool NOT NULL , comment int NULL REFERENCES Comment ON DELETE SET NULL, UNIQUE (left_entry, right_entry, relation) ); CREATE INDEX entry_pairs_left_index ON entry_pairs (left_entry); CREATE INDEX entry_pairs_right_index ON entry_pairs (right_entry); -- You get this" dblex=> explain select A.left_entry from entry_pairs A, entry_pairs B where A.right_entry != B.left_entry; NOTICE: QUERY PLAN: Nested Loop (cost=100000000.00..102876671.17 rows=97545252 width=12) -> Seq Scan on entry_pairs a (cost=0.00..167.77 rows=9877 width=8) -> Seq Scan on entry_pairs b (cost=0.00..167.77 rows=9877 width=4) EXPLAIN That is dum. If you just walk both B-Tree indexes there is a O(n) search. I tryed to turn off netsed loops but it still did it. (the reason the cost is 100000000.00 is a artifact from turing off loops) -Jonathan
On 15 Apr 2003, Jonathan Moore wrote: > I am wondering why it uses the O(n^2) nested loop when there is a O(N) > methoud using btree indexes for a merg join. I am using 7.2.1 would > upgrading fix my problime or is it somthing else? > > Given the schema: > > drop table Entry_Pairs; > create table Entry_Pairs ( > left_entry int REFERENCES Entry ON DELETE RESTRICT, > right_entry int REFERENCES Entry ON DELETE RESTRICT, > relation int NOT NULL , > subtract bool NOT NULL , > comment int NULL REFERENCES Comment ON DELETE SET NULL, > UNIQUE (left_entry, right_entry, relation) > ); > CREATE INDEX entry_pairs_left_index ON entry_pairs (left_entry); > CREATE INDEX entry_pairs_right_index ON entry_pairs (right_entry); > -- > > You get this" > > dblex=> explain select A.left_entry from entry_pairs A, entry_pairs B > where A.right_entry != B.left_entry; > NOTICE: QUERY PLAN: > > Nested Loop (cost=100000000.00..102876671.17 rows=97545252 width=12) > -> Seq Scan on entry_pairs a (cost=0.00..167.77 rows=9877 width=8) > -> Seq Scan on entry_pairs b (cost=0.00..167.77 rows=9877 width=4) > > EXPLAIN > > That is dum. If you just walk both B-Tree indexes there is a O(n) > search. I tryed to turn off netsed loops but it still did it. (the > reason the cost is 100000000.00 is a artifact from turing off loops) Can you describe the algorithm you think it should be taking with perhaps a small set of data like say (given only left and right): (1,2) (3,4) (5,6) (I think the query should return 1,1,1,3,3,3,5,5,5 for this case)
Jonathan Moore <moore@discern.com> writes: > I am wondering why it uses the O(n^2) nested loop when there is a O(N) > methoud using btree indexes for a merg join. With an inequality for the WHERE condition? I don't think so. The expected output is of size O(N^2), so how could the algorithm take less than O(N^2) steps? > dblex=> explain select A.left_entry from entry_pairs A, entry_pairs B > where A.right_entry != B.left_entry; regards, tom lane
Your WHERE clause is the reason you get O(N^2). How about describing in words what you want. maybe what you really want is: select left_entry from entry_pairs A where not exists ( select 1 from entry_pairs B where A.right_entry = B.left_entry) JLL Jonathan Moore wrote: > > I am wondering why it uses the O(n^2) nested loop when there is a O(N) > methoud using btree indexes for a merg join. I am using 7.2.1 would > upgrading fix my problime or is it somthing else? > > Given the schema: > > drop table Entry_Pairs; > create table Entry_Pairs ( > left_entry int REFERENCES Entry ON DELETE RESTRICT, > right_entry int REFERENCES Entry ON DELETE RESTRICT, > relation int NOT NULL , > subtract bool NOT NULL , > comment int NULL REFERENCES Comment ON DELETE SET NULL, > UNIQUE (left_entry, right_entry, relation) > ); > CREATE INDEX entry_pairs_left_index ON entry_pairs (left_entry); > CREATE INDEX entry_pairs_right_index ON entry_pairs (right_entry); > -- > > You get this" > > dblex=> explain select A.left_entry from entry_pairs A, entry_pairs B > where A.right_entry != B.left_entry; > NOTICE: QUERY PLAN: > > Nested Loop (cost=100000000.00..102876671.17 rows=97545252 width=12) > -> Seq Scan on entry_pairs a (cost=0.00..167.77 rows=9877 width=8) > -> Seq Scan on entry_pairs b (cost=0.00..167.77 rows=9877 width=4) > > EXPLAIN > > That is dum. If you just walk both B-Tree indexes there is a O(n) > search. I tryed to turn off netsed loops but it still did it. (the > reason the cost is 100000000.00 is a artifact from turing off loops) > > -Jonathan > > ---------------------------(end of broadcast)--------------------------- > TIP 6: Have you searched our list archives? > > http://archives.postgresql.org