OR clause status report

Started by Bruce Momjianover 27 years ago20 messages
#1Bruce Momjian
maillist@candle.pha.pa.us

I have succeeded in making OR clauses use indexes. I have not dealt
with some of the more complex issues like x=3 or y=5 as Vadim mentioned,
but at least it works.

test=> select * from test where x=102532 or x=102533;
x
------
102532
102533
(2 rows)

test=> explain select * from test where x=102532 or x=102533;
NOTICE: QUERY PLAN:

Index Scan using i_test on test (cost=4.10 size=1 width=4)

-- 
Bruce Momjian                          |  830 Blythe Avenue
maillist@candle.pha.pa.us              |  Drexel Hill, Pennsylvania 19026
  +  If your life is a hard drive,     |  (610) 353-9879(w)
  +  Christ can be your backup.        |  (610) 853-3000(h)
#2Vadim Mikheev
vadim@krs.ru
In reply to: Bruce Momjian (#1)
Re: [HACKERS] OR clause status report

Bruce Momjian wrote:

I have succeeded in making OR clauses use indexes. I have not dealt
with some of the more complex issues like x=3 or y=5 as Vadim mentioned,
but at least it works.

test=> select * from test where x=102532 or x=102533;

But did you care about the case when two indices (on test(x) and
on test(y)) exist ?

Vadim

#3Andreas Zeugswetter
andreas.zeugswetter@telecom.at
In reply to: Vadim Mikheev (#2)
AW: [HACKERS] OR clause status report

Vadim wrote:

Bruce Momjian wrote:

I have succeeded in making OR clauses use indexes. I have not dealt
with some of the more complex issues like x=3 or y=5 as Vadim mentioned,
but at least it works.

test=> select * from test where x=102532 or x=102533;

But did you care about the case when two indices (on test(x) and
on test(y)) exist ?

Do you mean using two indices in one access plan, or the decision which index to use ?

I think the case Bruce has fixed was the most important for those "alien MS Access users" among us.
Thanks Bruce !

Andreas

#4Vadim Mikheev
vadim@krs.ru
In reply to: Andreas Zeugswetter (#3)
Re: AW: [HACKERS] OR clause status report

Andreas Zeugswetter wrote:

Vadim wrote:

Bruce Momjian wrote:

I have succeeded in making OR clauses use indexes. I have not dealt
with some of the more complex issues like x=3 or y=5 as Vadim mentioned,
but at least it works.

test=> select * from test where x=102532 or x=102533;

But did you care about the case when two indices (on test(x) and
on test(y)) exist ?

Do you mean using two indices in one access plan, or the decision which index to use ?

^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
This.

Vadim

#5Vince Vielhaber
vev@michvhf.com
In reply to: Bruce Momjian (#1)
RE: [HACKERS] OR clause status report

On 31-Jul-98 Bruce Momjian wrote:

I have succeeded in making OR clauses use indexes. I have not dealt
with some of the more complex issues like x=3 or y=5 as Vadim
mentioned,
but at least it works.

test=> select * from test where x=102532 or x=102533;
x
------
102532
102533
(2 rows)

test=> explain select * from test where x=102532 or x=102533;
NOTICE: QUERY PLAN:

Index Scan using i_test on test (cost=4.10 size=1 width=4)

Now I've been wondering why my selects are so slow. Is this telling me
that they're NOT using the index? And if not, any ideas why?

The select returned 35 rows out of approx 170,000.

-----
campsites=> explain select * from locations where lower(city)='oxford';
NOTICE: QUERY PLAN:

Seq Scan on locations (cost=7263.30 size=84899 width=32)

EXPLAIN
campsites=>
-----

Vince.
--
==========================================================================
Vince Vielhaber -- KA8CSH email: vev@michvhf.com flame-mail: /dev/null
# include <std/disclaimers.h> TEAM-OS2
Online Searchable Campground Listings http://www.camping-usa.com
"There is no outfit less entitled to lecture me about bloat
than the federal government" -- Tony Snow
==========================================================================

#6Vadim Mikheev
vadim@krs.ru
In reply to: Vince Vielhaber (#5)
Re: [HACKERS] OR clause status report

Vince Vielhaber wrote:

Now I've been wondering why my selects are so slow. Is this telling me
that they're NOT using the index? And if not, any ideas why?

The select returned 35 rows out of approx 170,000.

-----
campsites=> explain select * from locations where lower(city)='oxford';

^^^^^^^^^^^
You should

create index index_name on locations (lower(city))
^^^^^
- this is known as functional index...

NOTICE: QUERY PLAN:

Seq Scan on locations (cost=7263.30 size=84899 width=32)

Vadim

#7Vince Vielhaber
vev@michvhf.com
In reply to: Vadim Mikheev (#6)
Re: [HACKERS] OR clause status report

On 31-Jul-98 Vadim Mikheev wrote:

Vince Vielhaber wrote:

Now I've been wondering why my selects are so slow. Is this telling
me
that they're NOT using the index? And if not, any ideas why?

The select returned 35 rows out of approx 170,000.

-----
campsites=> explain select * from locations where
lower(city)='oxford';

^^^^^^^^^^^
You should

create index index_name on locations (lower(city))
^^^^^
- this is known as functional index...

campsites=> create index lower_city on locations (lower(city));
ERROR: DefineIndex: (null) class not found
campsites=>

Hmmm..

Vince.
--
==========================================================================
Vince Vielhaber -- KA8CSH email: vev@michvhf.com flame-mail: /dev/null
# include <std/disclaimers.h> TEAM-OS2
Online Searchable Campground Listings http://www.camping-usa.com
"There is no outfit less entitled to lecture me about bloat
than the federal government" -- Tony Snow
==========================================================================

#8Vadim Mikheev
vadim@krs.ru
In reply to: Vince Vielhaber (#7)
Re: [HACKERS] OR clause status report

Vince Vielhaber wrote:

campsites=> create index lower_city on locations (lower(city));
ERROR: DefineIndex: (null) class not found
campsites=>

Ok, this works:

create index lower_city on locations (lower(city) text_ops);

Something broken in DefineIndex -:((
XXX_ops for function rettype should be used...

Vadim

#9Vadim Mikheev
vadim@krs.ru
In reply to: Andreas Zeugswetter (#3)
Re: AW: [HACKERS] OR clause status report

Vadim Mikheev wrote:

Andreas Zeugswetter wrote:

Vadim wrote:

Bruce Momjian wrote:

I have succeeded in making OR clauses use indexes. I have not dealt
with some of the more complex issues like x=3 or y=5 as Vadim mentioned,
but at least it works.

test=> select * from test where x=102532 or x=102533;

But did you care about the case when two indices (on test(x) and
on test(y)) exist ?

Do you mean using two indices in one access plan,

^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
This.

Actually, I meant NOT USING indices if both exist, because of
currently there is no check that tuples returned by second index
were not returned by first.

or the decision which index to use ?

Either both indices should be used or no one...

Also, Bruce, did you test the case (x = 5 or x > 4) ?
What about (x = 5 or x = 5)? - I'm not sure does cnfify()
get rid of duplicates or not...

Vadim

#10Vince Vielhaber
vev@michvhf.com
In reply to: Vadim Mikheev (#8)
Re: [HACKERS] OR clause status report

On 31-Jul-98 Vadim Mikheev wrote:

Vince Vielhaber wrote:

campsites=> create index lower_city on locations (lower(city));
ERROR: DefineIndex: (null) class not found
campsites=>

Ok, this works:

create index lower_city on locations (lower(city) text_ops);

Something broken in DefineIndex -:((
XXX_ops for function rettype should be used...

Yep, it created it that time but still won't use it. :(

Vince.
--
==========================================================================
Vince Vielhaber -- KA8CSH email: vev@michvhf.com flame-mail: /dev/null
# include <std/disclaimers.h> TEAM-OS2
Online Searchable Campground Listings http://www.camping-usa.com
"There is no outfit less entitled to lecture me about bloat
than the federal government" -- Tony Snow
==========================================================================

#11Bruce Momjian
maillist@candle.pha.pa.us
In reply to: Vadim Mikheev (#2)
Re: [HACKERS] OR clause status report

Bruce Momjian wrote:

I have succeeded in making OR clauses use indexes. I have not dealt
with some of the more complex issues like x=3 or y=5 as Vadim mentioned,
but at least it works.

test=> select * from test where x=102532 or x=102533;

But did you care about the case when two indices (on test(x) and
on test(y)) exist ?

Haven't gotten to that yet.

-- 
Bruce Momjian                          |  830 Blythe Avenue
maillist@candle.pha.pa.us              |  Drexel Hill, Pennsylvania 19026
  +  If your life is a hard drive,     |  (610) 353-9879(w)
  +  Christ can be your backup.        |  (610) 853-3000(h)
#12Bruce Momjian
maillist@candle.pha.pa.us
In reply to: Vadim Mikheev (#4)
Re: AW: [HACKERS] OR clause status report

Andreas Zeugswetter wrote:

Vadim wrote:

Bruce Momjian wrote:

I have succeeded in making OR clauses use indexes. I have not dealt
with some of the more complex issues like x=3 or y=5 as Vadim mentioned,
but at least it works.

test=> select * from test where x=102532 or x=102533;

But did you care about the case when two indices (on test(x) and
on test(y)) exist ?

Do you mean using two indices in one access plan, or the decision which index to use ?

^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
This.

Yes. I still need to run some tests. Just wanted people to know I had
gotten the trivial case working so far.

-- 
Bruce Momjian                          |  830 Blythe Avenue
maillist@candle.pha.pa.us              |  Drexel Hill, Pennsylvania 19026
  +  If your life is a hard drive,     |  (610) 353-9879(w)
  +  Christ can be your backup.        |  (610) 853-3000(h)
#13Vadim Mikheev
vadim@krs.ru
In reply to: Vince Vielhaber (#10)
1 attachment(s)
Re: [HACKERS] OR clause status report

Vince Vielhaber wrote:

Yep, it created it that time but still won't use it. :(

Yes, I see.

This is patch for 6.3.2
CVS updated.

Bruce, could you add this to TODO:

campsites=> create index lower_city on locations (lower(city));
ERROR: DefineIndex: (null) class not found
campsites=>

Ok, this works:

create index lower_city on locations (lower(city) text_ops);

Something broken in DefineIndex -:((
XXX_ops for function rettype should be used...

Should be easy to fix but no time -:(

Vadim

Attachments:

DFtext/plain; charset=us-ascii; name=DFDownload
*** src/backend/optimizer/path/indxpath.c.orig	Fri Jul 31 22:54:58 1998
--- src/backend/optimizer/path/indxpath.c	Fri Jul 31 22:56:38 1998
***************
*** 410,419 ****
  	int			curIndxKey;
  	Oid			curClass;
  
! 	if (clauseinfo_list == NIL)
  		return NIL;
  
! 	while (!DoneMatchingIndexKeys(indexkeys, index))
  	{
  		List	   *tempgroup = NIL;
  
--- 410,419 ----
  	int			curIndxKey;
  	Oid			curClass;
  
! 	if (clauseinfo_list == NIL || indexkeys[0] == 0)
  		return NIL;
  
! 	do
  	{
  		List	   *tempgroup = NIL;
  
***************
*** 443,449 ****
  		indexkeys++;
  		classes++;
  
! 	}
  
  	/* clausegroup holds all matched clauses ordered by indexkeys */
  
--- 443,449 ----
  		indexkeys++;
  		classes++;
  
! 	} while (!DoneMatchingIndexKeys(indexkeys, index));
  
  	/* clausegroup holds all matched clauses ordered by indexkeys */
  
***************
*** 474,483 ****
  	Oid			curClass;
  	bool		jfound = false;
  
! 	if (join_cinfo_list == NIL)
  		return NIL;
  
! 	while (!DoneMatchingIndexKeys(indexkeys, index))
  	{
  		List	   *tempgroup = NIL;
  
--- 474,483 ----
  	Oid			curClass;
  	bool		jfound = false;
  
! 	if (join_cinfo_list == NIL || indexkeys[0] == 0)
  		return NIL;
  
! 	do
  	{
  		List	   *tempgroup = NIL;
  
***************
*** 523,529 ****
  		indexkeys++;
  		classes++;
  
! 	}
  
  	/* clausegroup holds all matched clauses ordered by indexkeys */
  
--- 523,529 ----
  		indexkeys++;
  		classes++;
  
! 	} while (!DoneMatchingIndexKeys(indexkeys, index));
  
  	/* clausegroup holds all matched clauses ordered by indexkeys */
  
#14Bruce Momjian
maillist@candle.pha.pa.us
In reply to: Vadim Mikheev (#13)
Re: [HACKERS] OR clause status report

Vince Vielhaber wrote:

Yep, it created it that time but still won't use it. :(

Yes, I see.

This is patch for 6.3.2
CVS updated.

Bruce, could you add this to TODO:

campsites=> create index lower_city on locations (lower(city));
ERROR: DefineIndex: (null) class not found
campsites=>

Ok, this works:

create index lower_city on locations (lower(city) text_ops);

Something broken in DefineIndex -:((
XXX_ops for function rettype should be used...

Should be easy to fix but no time -:(

Added:

* allow creation of functional indexes to use default types

I am a little confused. You say you updated CVS. Isn't the change
installed already?

-- 
Bruce Momjian                          |  830 Blythe Avenue
maillist@candle.pha.pa.us              |  Drexel Hill, Pennsylvania 19026
  +  If your life is a hard drive,     |  (610) 353-9879(w)
  +  Christ can be your backup.        |  (610) 853-3000(h)
#15Vadim Mikheev
vadim@krs.ru
In reply to: Bruce Momjian (#14)
Re: [HACKERS] OR clause status report

Bruce Momjian wrote:

Added:

* allow creation of functional indexes to use default types

I am a little confused. You say you updated CVS. Isn't the change
installed already?

Functional indices were not used - this is fixed now and
fix is in CVS.

Vadim

#16Vince Vielhaber
vev@michvhf.com
In reply to: Vadim Mikheev (#13)
Re: [HACKERS] OR clause status report

On 31-Jul-98 Vadim Mikheev wrote:

Vince Vielhaber wrote:

Yep, it created it that time but still won't use it. :(

Yes, I see.

This is patch for 6.3.2
CVS updated.

campsites=> explain select * from locations where lower(city) = 'oxford';
NOTICE: QUERY PLAN:

Index Scan using lower_city on locations (cost=3608.95 size=56600 width=32)

EXPLAIN
campsites=>

Much better! Thanks! Now I get to upgrade the production machine.

Vince.
--
==========================================================================
Vince Vielhaber -- KA8CSH email: vev@michvhf.com flame-mail: /dev/null
# include <std/disclaimers.h> TEAM-OS2
Online Searchable Campground Listings http://www.camping-usa.com
"There is no outfit less entitled to lecture me about bloat
than the federal government" -- Tony Snow
==========================================================================

#17Vince Vielhaber
vev@michvhf.com
In reply to: Vince Vielhaber (#16)
Re: [HACKERS] OR clause status report - working

On 31-Jul-98 Vince Vielhaber wrote:

On 31-Jul-98 Vadim Mikheev wrote:

Vince Vielhaber wrote:

Yep, it created it that time but still won't use it. :(

Yes, I see.

This is patch for 6.3.2
CVS updated.

campsites=> explain select * from locations where lower(city) = 'oxford';
NOTICE: QUERY PLAN:

Index Scan using lower_city on locations (cost=3608.95 size=56600
width=32)

EXPLAIN
campsites=>

Much better! Thanks! Now I get to upgrade the production machine.

Ok, everything's working now but I did run into something unexpected.
The test machine (actually my desktop) has been running the cvsup'd
version since I set ip up a couple of weeks ago. The production machine
was running 6.3. The INSTALL file says dumping the db wasn't necessary
yet I had to - it wouldn't run without it and complained about the older
database. Is dumping going to be required for 6.4?

Also are indexes working for floats when the query uses BETWEEN?

Vince.
--
==========================================================================
Vince Vielhaber -- KA8CSH email: vev@michvhf.com flame-mail: /dev/null
# include <std/disclaimers.h> TEAM-OS2
Online Searchable Campground Listings http://www.camping-usa.com
"There is no outfit less entitled to lecture me about bloat
than the federal government" -- Tony Snow
==========================================================================

#18Thomas G. Lockhart
lockhart@alumni.caltech.edu
In reply to: Vince Vielhaber (#17)
Re: [HACKERS] OR clause status report - working

The test machine (actually my desktop) has been running the cvsup'd
version since I set ip up a couple of weeks ago. The production
machine was running 6.3. The INSTALL file says dumping the db wasn't
necessary yet I had to - it wouldn't run without it and complained
about the older database. Is dumping going to be required for 6.4?

Of course :)

Also, things like the installation docs are the last to be updated
before a release since they need to accurately match the actual release.
Pretty much a waste of time in between...

Also are indexes working for floats when the query uses BETWEEN?

Probably. The "BETWEEN" becomes an "AND" clause.

#19Vince Vielhaber
vev@michvhf.com
In reply to: Thomas G. Lockhart (#18)
Re: [HACKERS] OR clause status report - working

On 01-Aug-98 Thomas G. Lockhart wrote:

The test machine (actually my desktop) has been running the cvsup'd
version since I set ip up a couple of weeks ago. The production
machine was running 6.3. The INSTALL file says dumping the db wasn't
necessary yet I had to - it wouldn't run without it and complained
about the older database. Is dumping going to be required for 6.4?

Of course :)

Also, things like the installation docs are the last to be updated
before a release since they need to accurately match the actual release.
Pretty much a waste of time in between...

Ok, that makes real good sense to me. Just something to learn when using
a cvsup'd version as opposed to a release.

Also are indexes working for floats when the query uses BETWEEN?

Probably. The "BETWEEN" becomes an "AND" clause.

Unfortunately I later found this:

-----
campsites=> explain select name from camps3 where lon = 83.5555;
NOTICE: QUERY PLAN:

Seq Scan on camps3 (cost=822.87 size=1 width=12)

EXPLAIN
campsites=>
-----

I have two or three indexes created for lon on camps3.

create index camps3_lon on camps3 (lon);
create index camps3_lon2 on camps3 (lon, float4_ops);
create index camps3_loc on camps3 (lon, lat);

Vince.
--
==========================================================================
Vince Vielhaber -- KA8CSH email: vev@michvhf.com flame-mail: /dev/null
# include <std/disclaimers.h> TEAM-OS2
Online Searchable Campground Listings http://www.camping-usa.com
"There is no outfit less entitled to lecture me about bloat
than the federal government" -- Tony Snow
==========================================================================

#20Bruce Momjian
maillist@candle.pha.pa.us
In reply to: Vadim Mikheev (#9)
Re: AW: [HACKERS] OR clause status report

Vadim Mikheev wrote:

Andreas Zeugswetter wrote:

Vadim wrote:

Bruce Momjian wrote:

I have succeeded in making OR clauses use indexes. I have not dealt
with some of the more complex issues like x=3 or y=5 as Vadim mentioned,
but at least it works.

test=> select * from test where x=102532 or x=102533;

But did you care about the case when two indices (on test(x) and
on test(y)) exist ?

Do you mean using two indices in one access plan,

^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
This.

Actually, I meant NOT USING indices if both exist, because of
currently there is no check that tuples returned by second index
were not returned by first.

or the decision which index to use ?

Either both indices should be used or no one...

Also, Bruce, did you test the case (x = 5 or x > 4) ?
What about (x = 5 or x = 5)? - I'm not sure does cnfify()
get rid of duplicates or not...

It does get rid of duplicates, and only uses indexes if ALL clauses have
an availble index, but as you noted, x=5 or x > 4 must be handled. It
works now:

test=> select * from test where x >= 102665 or x= 102665;
x
------
102665
(1 row)

test=> explain select * from test where x >= 102665 or x= 102665;
NOTICE: QUERY PLAN:

Index Scan using i_test on test (cost=1503.32 size=1 width=4)

I do it with this code:

ExecStoreTuple(tuple, /* tuple to store */
slot, /* slot to store in */
buffer, /* buffer associated with tuple */
false); /* don't pfree */

for (prev_index = 0; prev_index < indexstate->iss_IndexPtr;
prev_index++)
{
if (ExecQual(nth(prev_index, node->indxqual),
scanstate->cstate.cs_ExprContext))
{
prev_matches = true;
break;
}
}
if (!prev_matches)
return slot;

On an index scan, I compare the qualifications of previous OR index
scans, and return the row only if the current row does not match one of
the previous qualifications. Sounds like a winner. I have not yet
committed this code to the CVS tree.

-- 
Bruce Momjian                          |  830 Blythe Avenue
maillist@candle.pha.pa.us              |  Drexel Hill, Pennsylvania 19026
  +  If your life is a hard drive,     |  (610) 353-9879(w)
  +  Christ can be your backup.        |  (610) 853-3000(h)