Thread: Index not used in query. Why?
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.
"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
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 >
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)