Oracle FAQ | Your Portal to the Oracle Knowledge Grid |
![]() |
![]() |
Home -> Community -> Usenet -> c.d.o.server -> Re: Why doesnt this query work?? Makes no sense????
In article <8jqe83$nt2$1_at_nnrp1.deja.com>,
ddf_dba_at_my-deja.com wrote:
> In article <8jbha5$8eo$1_at_nnrp1.deja.com>,
> Thomas J. Kyte <tkyte_at_us.oracle.com> wrote:
> > In article <3959413e.5520978_at_news.mindspring.com>,
> > nitefrog_at_yahoo.com wrote:
> > > Why does this query not return any rows? I cant figure this one
out?
> > > Also I want to note that the tablespaces are full or very close to
> > > being according to the storage manager. Will this cause the
problem?
> > > Also this query takes for ever to run as well. Any help is
greatly
> > > appreciated.
> > >
> > > select patientid
> > > from B
> > > where patientid not in (select patientid from A);
> > >
[snip]
> >
> > you have a NULL patientid in table A. When you say "where x not in
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
[snip]
>
> I don't know which version of Oracle you are running, Tom, but I
cannot
> get Oracle to exhibit the same behavior on 8.1.5:
>
you put the NULL row into the wrong table. Put a NULL row into tableA, not table B. Its the thing in the NOT IN ( .... ) that is the cause.
> SQL> create table a(patientid int, constraint a_pk primary
> key(patientid));
>
>
>
>
>
thats the mistake.
[snip]
>
> The NULL value does not appear to affect the query speed or the
results
> as you state. Again, maybe you're on a different release of Oracle.
>
No, i'm on 7.x, 8.0.x, 8.1.x..... they are all the same. Trust me on this one.
with a trivial amount of data, you'll see trivial runtimes. With lots of data -- you'll see a much LARGER runtime. Try this one:
ops$tkyte_at_8i> create table a as select -rownum patient_id from all_objects where rownum < 1000;
Table created.
Elapsed: 00:00:00.22
ops$tkyte_at_8i> create table b as select rownum patient_id from
all_objects where rownum < 1000;
Table created.
Elapsed: 00:00:00.21
ops$tkyte_at_8i>
ops$tkyte_at_8i> alter table a add constraint a_unique unique(patient_id);
Table altered.
Elapsed: 00:00:00.07
ops$tkyte_at_8i> alter table b add constraint b_pk primary key(patient_id);
Table altered.
Elapsed: 00:00:00.07
ops$tkyte_at_8i>
ops$tkyte_at_8i> select count(*)
2 from B
3 where patient_id NOT IN ( select patient_id from A )
4 /
COUNT(*)
999
Elapsed: 00:00:01.89
ops$tkyte_at_8i>
Takes a bit of time -- just to show its not "cause it ain't cached", we'll do it all over again:
ops$tkyte_at_8i> select count(*)
2 from B
3 where patient_id NOT IN ( select patient_id from A )
4 /
COUNT(*)
999
Elapsed: 00:00:01.79
Not any faster really..... Now, lets try it in a method that allows for indexes:
ops$tkyte_at_8i>
ops$tkyte_at_8i> select count(*)
2 from B
3 where NOT EXISTS ( select null from a where a.patient_id =
b.patient_id )
4 /
COUNT(*)
999
Elapsed: 00:00:00.03
ops$tkyte_at_8i>
Thats much faster. Now, lets put that nasty NULL into the correct table:
ops$tkyte_at_8i> insert into a values ( NULL );
1 row created.
Elapsed: 00:00:00.00
ops$tkyte_at_8i>
ops$tkyte_at_8i> select count(*)
2 from B
3 where patient_id NOT IN ( select patient_id from A )
4 /
COUNT(*)
0
Elapsed: 00:00:01.65
ops$tkyte_at_8i>
ops$tkyte_at_8i> select count(*)
2 from B
3 where NOT EXISTS ( select null from a where a.patient_id =
b.patient_id )
4 /
COUNT(*)
999
Elapsed: 00:00:00.02
ops$tkyte_at_8i>
And the semantic differences between NOT IN and NOT EXISTS become apparent.
The advice I gave the first time (rewrite the query using "where patient_id is not null" in the subquery and using CBO to allow for the HASH anti-join or index probes, or using NOT EXISTS with RBO) is correct.
> --
> David Fitzjarrell
> Oracle Certified DBA
>
-- Thomas Kyte (tkyte_at_us.oracle.com) Oracle Service Industries Howtos and such: http://osi.oracle.com/~tkyte/index.html Oracle Magazine: http://www.oracle.com/oramag Opinions are mine and do not necessarily reflect those of Oracle Corp Sent via Deja.com http://www.deja.com/ Before you buy.Received on Mon Jul 03 2000 - 00:00:00 CDT
![]() |
![]() |