Thread: Index not used in query. Why?

Index not used in query. Why?

From
"Andrei Bintintan"
Date:
Hi to all! I have the following query. The execution time is very big, it
doesn't use the indexes and I don't understand why...


SELECT count(o.id)  FROM orders o

                                   INNER JOIN report r ON o.id=r.id_order

                                   INNER JOIN status s ON o.id_status=s.id

                                   INNER JOIN contact c ON o.id_ag=c.id

                                   INNER JOIN endkunde e ON
o.id_endkunde=e.id

                                   INNER JOIN zufriden z ON
r.id_zufriden=z.id

                                   INNER JOIN plannung v ON
v.id=o.id_plannung

                                   INNER JOIN mpsworker w ON
v.id_worker=w.id

                                   INNER JOIN person p ON p.id = w.id_person

                                   WHERE o.id_status > 3

The query explain:



Aggregate  (cost=32027.38..32027.38 rows=1 width=4)

  ->  Hash Join  (cost=23182.06..31944.82 rows=33022 width=4)

        Hash Cond: ("outer".id_person = "inner".id)

        ->  Hash Join  (cost=23179.42..31446.85 rows=33022 width=8)

              Hash Cond: ("outer".id_endkunde = "inner".id)

              ->  Hash Join  (cost=21873.54..28891.42 rows=33022 width=12)

                    Hash Cond: ("outer".id_ag = "inner".id)

                    ->  Hash Join  (cost=21710.05..28067.50 rows=33021
width=16)

                          Hash Cond: ("outer".id_status = "inner".id)

                          ->  Hash Join  (cost=21708.97..27571.11 rows=33021
width=20)

                                Hash Cond: ("outer".id_worker = "inner".id)

                                ->  Hash Join  (cost=21707.49..27074.31
rows=33021 width=20)

                                      Hash Cond: ("outer".id_zufriden =
"inner".id)

                                      ->  Hash Join
(cost=21706.34..26564.09 rows=35772 width=24)

                                            Hash Cond: ("outer".id_plannung
= "inner".id)

                                            ->  Hash Join
(cost=20447.15..23674.04 rows=35771 width=24)

                                                  Hash Cond: ("outer".id =
"inner".id_order)

                                                  ->  Seq Scan on orders o
(cost=0.00..1770.67 rows=36967 width=20)

                                                        Filter: (id_status >
3)

                                                  ->  Hash
(cost=20208.32..20208.32 rows=37132 width=8)

                                                        ->  Seq Scan on
report r  (cost=0.00..20208.32 rows=37132 width=8)

                                            ->  Hash  (cost=913.15..913.15
rows=54015 width=8)

                                                  ->  Seq Scan on plannung v
(cost=0.00..913.15 rows=54015 width=8)

                                      ->  Hash  (cost=1.12..1.12 rows=12
width=4)

                                            ->  Seq Scan on zufriden z
(cost=0.00..1.12 rows=12 width=4)

                                ->  Hash  (cost=1.39..1.39 rows=39 width=8)

                                      ->  Seq Scan on mpsworker w
(cost=0.00..1.39 rows=39 width=8)

                          ->  Hash  (cost=1.06..1.06 rows=6 width=4)

                                ->  Seq Scan on status s  (cost=0.00..1.06
rows=6 width=4)

                    ->  Hash  (cost=153.19..153.19 rows=4119 width=4)

                          ->  Seq Scan on contact c  (cost=0.00..153.19
rows=4119 width=4)

              ->  Hash  (cost=1077.91..1077.91 rows=38391 width=4)

                    ->  Seq Scan on endkunde e  (cost=0.00..1077.91
rows=38391 width=4)

        ->  Hash  (cost=2.51..2.51 rows=51 width=4)

              ->  Seq Scan on person p  (cost=0.00..2.51 rows=51 width=4)





As you can see, no index is used.I made everywhere indexes where the jons
are made. If I use the following query the indexes are used:



SELECT count(o.id)  FROM orders o

                                   INNER JOIN report r ON o.id=r.id_order

                                   INNER JOIN status s ON o.id_status=s.id

                                   INNER JOIN contact c ON o.id_ag=c.id

                                   INNER JOIN endkunde e ON
o.id_endkunde=e.id

                                   INNER JOIN zufriden z ON
r.id_zufriden=z.id

                                   INNER JOIN plannung v ON
v.id=o.id_plannung

                                   INNER JOIN mpsworker w ON
v.id_worker=w.id

                                   INNER JOIN person p ON p.id = w.id_person

                                   WHERE o.id_status =4



Aggregate  (cost=985.55..985.55 rows=1 width=4)

  ->  Hash Join  (cost=5.28..985.42 rows=50 width=4)

        Hash Cond: ("outer".id_person = "inner".id)

        ->  Hash Join  (cost=2.64..982.03 rows=50 width=8)

              Hash Cond: ("outer".id_worker = "inner".id)

              ->  Nested Loop  (cost=1.15..979.79 rows=50 width=8)

                    ->  Nested Loop  (cost=1.15..769.64 rows=49 width=8)

                          ->  Nested Loop  (cost=1.15..535.57 rows=48
width=12)

                                ->  Seq Scan on status s  (cost=0.00..1.07
rows=1 width=4)

                                      Filter: (4 = id)

                                ->  Nested Loop  (cost=1.15..534.01 rows=48
width=16)

                                      ->  Hash Join  (cost=1.15..366.37
rows=47 width=20)

                                            Hash Cond: ("outer".id_zufriden
= "inner".id)

                                            ->  Nested Loop
(cost=0.00..364.48 rows=51 width=24)

                                                  ->  Index Scan using
orders_id_status_idx on orders o  (cost=0.00..69.55 rows=52 width=20)

                                                        Index Cond:
(id_status = 4)

                                                  ->  Index Scan using
report_id_order_idx on report r  (cost=0.00..5.66 rows=1 width=8)

                                                        Index Cond:
("outer".id = r.id_order)

                                            ->  Hash  (cost=1.12..1.12
rows=12 width=4)

                                                  ->  Seq Scan on zufriden z
(cost=0.00..1.12 rows=12 width=4)

                                      ->  Index Scan using endkunde_pkey on
endkunde e  (cost=0.00..3.55 rows=1 width=4)

                                            Index Cond: ("outer".id_endkunde
= e.id)

                          ->  Index Scan using contact_pkey on contact c
(cost=0.00..4.86 rows=1 width=4)

                                Index Cond: ("outer".id_ag = c.id)

                    ->  Index Scan using plannung_pkey on plannung v
(cost=0.00..4.28 rows=1 width=8)

                          Index Cond: (v.id = "outer".id_plannung)

              ->  Hash  (cost=1.39..1.39 rows=39 width=8)

                    ->  Seq Scan on mpsworker w  (cost=0.00..1.39 rows=39
width=8)

        ->  Hash  (cost=2.51..2.51 rows=51 width=4)

              ->  Seq Scan on person p  (cost=0.00..2.51 rows=51 width=4)





Best regards,

Andy.




Re: Index not used in query. Why?

From
Tom Lane
Date:
"Andrei Bintintan" <klodoma@ar-sd.net> writes:
> Hi to all! I have the following query. The execution time is very big, it
> doesn't use the indexes and I don't understand why...

Indexes are not necessarily the best way to do a large join.

> If I use the following query the indexes are used:

The key reason this wins seems to be that the id_status = 4 condition
is far more selective than id_status > 3 (the estimates are 52 and 36967
rows respectively ... is that accurate?) which means that the second
query is inherently about 1/700th as much work.  This, and not the use
of indexes, is the fundamental reason why it's faster.

            regards, tom lane

Re: Index not used in query. Why?

From
"Contact AR-SD.NET"
Date:
Is there a solution to make it faster?
At the end I need only in the query the id_status =4 and 6, but if I write
in the sql query (where condition) where id_status in (4,6), the explain
says the same(the slow version).

For example:
SELECT count(o.id)  FROM orders o
                                   INNER JOIN report r ON o.id=r.id_order
                                   INNER JOIN status s ON o.id_status=s.id
                                   INNER JOIN contact c ON o.id_ag=c.id
                                   INNER JOIN endkunde e ON
o.id_endkunde=e.id
                                   INNER JOIN zufriden z ON
r.id_zufriden=z.id
                                   INNER JOIN plannung v ON
v.id=o.id_plannung
                                   INNER JOIN mpsworker w ON
v.id_worker=w.id
                                   INNER JOIN person p ON p.id = w.id_person
                                   WHERE o.id_status in (4,6);

The result for this query is also without index searches.

I really have to make this query a little more faster. Suggestions?

Regards,
Andy.

----- Original Message -----
From: "Tom Lane" <tgl@sss.pgh.pa.us>
To: "Andrei Bintintan" <klodoma@ar-sd.net>
Cc: <pgsql-performance@postgresql.org>
Sent: Tuesday, October 19, 2004 7:52 PM
Subject: Re: [PERFORM] Index not used in query. Why?


> "Andrei Bintintan" <klodoma@ar-sd.net> writes:
> > Hi to all! I have the following query. The execution time is very big,
it
> > doesn't use the indexes and I don't understand why...
>
> Indexes are not necessarily the best way to do a large join.
>
> > If I use the following query the indexes are used:
>
> The key reason this wins seems to be that the id_status = 4 condition
> is far more selective than id_status > 3 (the estimates are 52 and 36967
> rows respectively ... is that accurate?) which means that the second
> query is inherently about 1/700th as much work.  This, and not the use
> of indexes, is the fundamental reason why it's faster.
>
> regards, tom lane
>
> ---------------------------(end of broadcast)---------------------------
> TIP 4: Don't 'kill -9' the postmaster
>


Re: Index not used in query. Why?

From
Thomas F.O'Connell
Date:
There's a chance that you could gain from quoting the '4' and '6' if
those orders.id_status isn't a pure int column and is indexed.

See http://www.postgresql.org/docs/7.4/static/datatype.html#DATATYPE-INT

-tfo

--
Thomas F. O'Connell
Co-Founder, Information Architect
Sitening, LLC
http://www.sitening.com/
110 30th Avenue North, Suite 6
Nashville, TN 37203-6320
615-260-0005

On Oct 19, 2004, at 12:49 PM, Contact AR-SD.NET wrote:

> Is there a solution to make it faster?
> At the end I need only in the query the id_status =4 and 6, but if I
> write
> in the sql query (where condition) where id_status in (4,6), the
> explain
> says the same(the slow version).
>
> For example:
> SELECT count(o.id)  FROM orders o
>                                    INNER JOIN report r ON
> o.id=r.id_order
>                                    INNER JOIN status s ON
> o.id_status=s.id
>                                    INNER JOIN contact c ON o.id_ag=c.id
>                                    INNER JOIN endkunde e ON
> o.id_endkunde=e.id
>                                    INNER JOIN zufriden z ON
> r.id_zufriden=z.id
>                                    INNER JOIN plannung v ON
> v.id=o.id_plannung
>                                    INNER JOIN mpsworker w ON
> v.id_worker=w.id
>                                    INNER JOIN person p ON p.id =
> w.id_person
>                                    WHERE o.id_status in (4,6);
>
> The result for this query is also without index searches.
>
> I really have to make this query a little more faster. Suggestions?
>
> Regards,
> Andy.
>
> ----- Original Message -----
> From: "Tom Lane" <tgl@sss.pgh.pa.us>
> To: "Andrei Bintintan" <klodoma@ar-sd.net>
> Cc: <pgsql-performance@postgresql.org>
> Sent: Tuesday, October 19, 2004 7:52 PM
> Subject: Re: [PERFORM] Index not used in query. Why?
>
>
>> "Andrei Bintintan" <klodoma@ar-sd.net> writes:
>>> Hi to all! I have the following query. The execution time is very
>>> big,
> it
>>> doesn't use the indexes and I don't understand why...
>>
>> Indexes are not necessarily the best way to do a large join.
>>
>>> If I use the following query the indexes are used:
>>
>> The key reason this wins seems to be that the id_status = 4 condition
>> is far more selective than id_status > 3 (the estimates are 52 and
>> 36967
>> rows respectively ... is that accurate?) which means that the second
>> query is inherently about 1/700th as much work.  This, and not the use
>> of indexes, is the fundamental reason why it's faster.
>>
>> regards, tom lane
>>
>> ---------------------------(end of
>> broadcast)---------------------------
>> TIP 4: Don't 'kill -9' the postmaster
>>
>
>
> ---------------------------(end of
> broadcast)---------------------------
> TIP 2: you can get off all lists at once with the unregister command
>     (send "unregister YourEmailAddressHere" to
> majordomo@postgresql.org)