Обсуждение: IN or EXISTS?? faster one

Поиск
Список
Период
Сортировка

IN or EXISTS?? faster one

От
"Prachi Jain"
Дата:
Hello All,

I am using too many subqueries in my queries. I have read some
FAQs that using EXISTS is faster than IN. Is that correct?? I
tried to get the total runtime using EXPLAIN ANALYZE, but i got
total runtime for the query with IN but not for the query with
EXISTS.

query with IN:

EXPLAIN ANALYZE Select * from bom where depot_id in ( SELECT
depot_id from depot where company_name ='SOME' );

query with EXISTS:
EXPLAIN ANALYZE  Select * from bom WHERE EXISTS ( SELECT depot_id
 from depot where company_name ='SOME' and depot.depot_id =
bom.depot_id );

I read the same for using with select count(*)...is too slow. How
to replace for that??

Moreover, what are the other things one should take care of
regarding reducing the time taken by the queries??

Thanks in advance.
Regards
Prachi



Re: IN or EXISTS?? faster one

От
Manfred Koizar
Дата:
On 19 Dec 2002 13:09:47 -0000, "Prachi Jain"
<prachijain3@rediffmail.com> wrote:
>I am using too many subqueries in my queries. I have read some
>FAQs that using EXISTS is faster than IN. Is that correct?? I
>tried to get the total runtime using EXPLAIN ANALYZE, but i got
>total runtime for the query with IN but not for the query with
>EXISTS.

What do you mean by "EXPLAIN ANALYZE ... not for the query with
EXISTS"?  Was there an error?

>EXPLAIN ANALYZE Select * from bom where depot_id in ( SELECT
>depot_id from depot where company_name ='SOME' );
>
>EXPLAIN ANALYZE  Select * from bom WHERE EXISTS ( SELECT depot_id
> from depot where company_name ='SOME' and depot.depot_id =
>bom.depot_id );

Assuming depot_id is unique in depot, you could also write

    SELECT bom.*
      FROM bom INNER JOIN depot d ON bom.depot_id=d.depot_id
     WHERE d.company_name ='SOME';

or

    SELECT bom.*
      FROM bom, depot d
     WHERE bom.depot_id = d.depot_id
       AND d.company_name = 'SOME';

and let the query optimizer find a good plan.

Servus
 Manfred

Re: IN or EXISTS?? faster one

От
Scott Lamb
Дата:
Manfred Koizar wrote:
> On 19 Dec 2002 13:09:47 -0000, "Prachi Jain"
> <prachijain3@rediffmail.com> wrote:
>
>>I am using too many subqueries in my queries. I have read some
>>FAQs that using EXISTS is faster than IN. Is that correct?? I
>>tried to get the total runtime using EXPLAIN ANALYZE, but i got
>>total runtime for the query with IN but not for the query with
>>EXISTS.
>
>
> What do you mean by "EXPLAIN ANALYZE ... not for the query with
> EXISTS"?  Was there an error?
>
>
>>EXPLAIN ANALYZE Select * from bom where depot_id in ( SELECT
>>depot_id from depot where company_name ='SOME' );
>>
>>EXPLAIN ANALYZE  Select * from bom WHERE EXISTS ( SELECT depot_id
>>from depot where company_name ='SOME' and depot.depot_id =
>>bom.depot_id );
>
>
> Assuming depot_id is unique in depot, you could also write

that's also assuming d.company_name is distinct in depot. Otherwise
you'll get repeated bom.*s for each d it matches. A "distinct" would
solve this.

>     SELECT bom.*
>       FROM bom INNER JOIN depot d ON bom.depot_id=d.depot_id
>      WHERE d.company_name ='SOME';
>
> or
>
>     SELECT bom.*
>       FROM bom, depot d
>      WHERE bom.depot_id = d.depot_id
>        AND d.company_name = 'SOME';
>
> and let the query optimizer find a good plan.

Scott


Re: IN or EXISTS?? faster one

От
Manfred Koizar
Дата:
On Fri, 20 Dec 2002 04:18:42 -0600, Scott Lamb <slamb@slamb.org>
wrote:
>that's also assuming d.company_name is distinct in depot.

No, it's not.

CREATE TABLE depot (depot_id INT, company_name TEXT);
INSERT INTO depot VALUES (1, 'SOME');
INSERT INTO depot VALUES (2, 'ANY');
INSERT INTO depot VALUES (3, 'SOME');

CREATE TABLE bom (bom_id int, depot_id int);
INSERT INTO bom VALUES (11, 1);
INSERT INTO bom VALUES (12, 2);
INSERT INTO bom VALUES (13, 3);
INSERT INTO bom VALUES (14, 4);
INSERT INTO bom VALUES (21, 1);
INSERT INTO bom VALUES (22, 2);
INSERT INTO bom VALUES (23, 3);

SELECT bom.*
  FROM bom, depot d
 WHERE bom.depot_id = d.depot_id
   AND d.company_name = 'SOME';

SELECT bom.*
  FROM bom INNER JOIN depot d ON bom.depot_id=d.depot_id
 WHERE d.company_name ='SOME';

> Otherwise
>you'll get repeated bom.*s for each d it matches.

No repeatd boms here:
 bom_id | depot_id
--------+----------
     11 |        1
     13 |        3
     21 |        1
     23 |        3
(4 rows)

The point is: there can be many depots matching company_name='SOME',
but there's at most one matching depot for each bom.

Servus
 Manfred

Re: IN or EXISTS?? faster one

От
Scott Lamb
Дата:
Manfred Koizar wrote:
> On Fri, 20 Dec 2002 04:18:42 -0600, Scott Lamb <slamb@slamb.org>
> wrote:
>
>>that's also assuming d.company_name is distinct in depot.
>
>
> No, it's not.

My bad. That's what happens when I post at 4:18 AM. ;)

Scott


Re: IN or EXISTS?? faster one

От
Manfred Koizar
Дата:
On Fri, 20 Dec 2002 10:51:54 -0600, Scott Lamb <slamb@slamb.org>
wrote:
>That's what happens when I post at 4:18 AM. ;)

Sometimes when I don't like the weather I think I live in the wrong
climate zone.  ISTM *you* live in the wrong time zone, you should move
to Europe.  At least!  :-)

Servus
 Manfred

Re: IN or EXISTS?? faster one

От
Lucky Leavell
Дата:

On 19 Dec 2002, Prachi Jain wrote:

> Hello All,
>
> I am using too many subqueries in my queries. I have read some
> FAQs that using EXISTS is faster than IN. Is that correct??

In general, with any RDBMS, the EXISTS construct is faster because the
subselect need only the first row to satisfy the condition whereas IN must
return all rows from the subselect.  (Of course, the query optimizer must
take advantage of that fact ...)

(I am rather new to PostgrSQL but an old hand - in more ways than one <G>-
with commercial Ingres.)

Lucky Leavell