[EXPLAIN] Nested loops

Started by Reg Me Pleaseover 17 years ago7 messagesgeneral
Jump to latest
#1Reg Me Please
regmeplease@gmail.com

Hi.

For an INNER JOINed query, EXPLAIN says that a "nested loop" is responsible
for the big part of the time needed to run.

The 2 tables JOINed are:

T1: multi-million rows
T2: few dozens rows

The join is though a single column in both sides and it's NOT a PK in either
table. But I have indexes in both T1 and T2 for that column.

I've read in the "Explaining EXPLAIN" by Rober Treat
(at http://wiki.postgresql.org/wiki/Image:OSCON2005-ExplainingExplain.sxi)
that this nested loop can be slow because of lacking of indexes.

Is there any hint to try to speed that query up?

As of now, only a REINDEX can help thanks to caching, I presume.
But the EXPLAIN still says there's a slow nested loop.

--
Fahrbahn ist ein graues Band
weisse Streifen, grüner Rand

#2Victor Nawothnig
victor.nawothnig@gmail.com
In reply to: Reg Me Please (#1)
Re: [EXPLAIN] Nested loops

Could you provide the output of EXPLAIN ANALYZE with your query?

Show quoted text

On Fri, Jan 9, 2009 at 7:06 PM, Reg Me Please <regmeplease@gmail.com> wrote:

Hi.

For an INNER JOINed query, EXPLAIN says that a "nested loop" is responsible
for the big part of the time needed to run.

The 2 tables JOINed are:

T1: multi-million rows
T2: few dozens rows

The join is though a single column in both sides and it's NOT a PK in either
table. But I have indexes in both T1 and T2 for that column.

I've read in the "Explaining EXPLAIN" by Rober Treat
(at http://wiki.postgresql.org/wiki/Image:OSCON2005-ExplainingExplain.sxi)
that this nested loop can be slow because of lacking of indexes.

Is there any hint to try to speed that query up?

As of now, only a REINDEX can help thanks to caching, I presume.
But the EXPLAIN still says there's a slow nested loop.

--
Fahrbahn ist ein graues Band
weisse Streifen, grüner Rand

--
Sent via pgsql-general mailing list (pgsql-general@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-general

#3Reg Me Please
regmeplease@gmail.com
In reply to: Victor Nawothnig (#2)
Re: [EXPLAIN] Nested loops

Here it comes:

Aggregate (cost=227.59..227.61 rows=1 width=8)
-> Nested Loop (cost=0.00..227.34 rows=49 width=8)
-> Seq Scan on T2 (cost=0.00..1.07 rows=6 width=4)
Filter: (fld1 = 'VEND'::text)
-> Index Scan using i_T1_partial on T1 (cost=0.00..37.61 rows=8
width=8)
Index Cond: ((T1.prod_id = 42) AND (T1.fk1 = T2.fk1))

On Friday 09 January 2009 19:22:28 Victor Nawothnig wrote:

Could you provide the output of EXPLAIN ANALYZE with your query?

On Fri, Jan 9, 2009 at 7:06 PM, Reg Me Please <regmeplease@gmail.com> wrote:

Hi.

For an INNER JOINed query, EXPLAIN says that a "nested loop" is
responsible for the big part of the time needed to run.

The 2 tables JOINed are:

T1: multi-million rows
T2: few dozens rows

The join is though a single column in both sides and it's NOT a PK in
either table. But I have indexes in both T1 and T2 for that column.

I've read in the "Explaining EXPLAIN" by Rober Treat
(at
http://wiki.postgresql.org/wiki/Image:OSCON2005-ExplainingExplain.sxi)
that this nested loop can be slow because of lacking of indexes.

Is there any hint to try to speed that query up?

As of now, only a REINDEX can help thanks to caching, I presume.
But the EXPLAIN still says there's a slow nested loop.

--
Fahrbahn ist ein graues Band
weisse Streifen, grüner Rand

--
Sent via pgsql-general mailing list (pgsql-general@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-general

--
--
Fahrbahn ist ein graues Band
weisse Streifen, grüner Rand

#4Thomas Pundt
mlists@rp-online.de
In reply to: Reg Me Please (#3)
Re: [EXPLAIN] Nested loops

Reg Me Please wrote:

Here it comes:

Aggregate (cost=227.59..227.61 rows=1 width=8)
-> Nested Loop (cost=0.00..227.34 rows=49 width=8)
-> Seq Scan on T2 (cost=0.00..1.07 rows=6 width=4)
Filter: (fld1 = 'VEND'::text)
-> Index Scan using i_T1_partial on T1 (cost=0.00..37.61 rows=8
width=8)
Index Cond: ((T1.prod_id = 42) AND (T1.fk1 = T2.fk1))

That's the EXPLAIN output, _not_ EXPLAIN ANALYZE as requested.

Probably statistics aren't up-to-date?

Thomas

#5Tom Lane
tgl@sss.pgh.pa.us
In reply to: Reg Me Please (#3)
Re: [EXPLAIN] Nested loops

Reg Me Please <regmeplease@gmail.com> writes:

Aggregate (cost=227.59..227.61 rows=1 width=8)
-> Nested Loop (cost=0.00..227.34 rows=49 width=8)
-> Seq Scan on T2 (cost=0.00..1.07 rows=6 width=4)
Filter: (fld1 = 'VEND'::text)
-> Index Scan using i_T1_partial on T1 (cost=0.00..37.61 rows=8
width=8)
Index Cond: ((T1.prod_id = 42) AND (T1.fk1 = T2.fk1))

If those rowcount estimates are accurate, then this is a perfectly good
plan; in fact probably the best you could hope for.

regards, tom lane

#6Reg Me Please
regmeplease@gmail.com
In reply to: Thomas Pundt (#4)
Re: [EXPLAIN] Nested loops

On Friday 09 January 2009 20:00:36 Thomas Pundt wrote:

Reg Me Please wrote:

Here it comes:

Aggregate (cost=227.59..227.61 rows=1 width=8)
-> Nested Loop (cost=0.00..227.34 rows=49 width=8)
-> Seq Scan on T2 (cost=0.00..1.07 rows=6 width=4)
Filter: (fld1 = 'VEND'::text)
-> Index Scan using i_T1_partial on T1 (cost=0.00..37.61
rows=8 width=8)
Index Cond: ((T1.prod_id = 42) AND (T1.fk1 = T2.fk1))

That's the EXPLAIN output, _not_ EXPLAIN ANALYZE as requested.

Probably statistics aren't up-to-date?

Thomas

Correct!
I changed a value in the WHERE condition to avoid some caching (maybe useless
in this case).

QUERY PLAN
-------------------------------------------------------------------------------------------------------------------------------------------------------------------
Aggregate (cost=227.59..227.61 rows=1 width=8) (actual time=151.722..151.723
rows=1 loops=1)
-> Nested Loop (cost=0.00..227.34 rows=49 width=8) (actual
time=25.157..151.507 rows=44 loops=1)
-> Seq Scan on T2 (cost=0.00..1.07 rows=6 width=4) (actual
time=0.015..0.032 rows=6 loops=1)
Filter: (fld1 = 'VEND'::text)
-> Index Scan using i_T1_partial on T1 (cost=0.00..37.61 rows=8
width=8) (actual time=5.435..25.226 rows=7 loops=6)
Index Cond: ((T1.prod_id = 4242) AND (T1.fk1 = T2.fk1))
Total runtime: 151.818 ms
(7 rows)

--
Fahrbahn ist ein graues Band
weisse Streifen, grüner Rand

#7Reg Me Please
regmeplease@gmail.com
In reply to: Tom Lane (#5)
Re: [EXPLAIN] Nested loops

On Friday 09 January 2009 20:00:57 Tom Lane wrote:

Reg Me Please <regmeplease@gmail.com> writes:

Aggregate (cost=227.59..227.61 rows=1 width=8)
-> Nested Loop (cost=0.00..227.34 rows=49 width=8)
-> Seq Scan on T2 (cost=0.00..1.07 rows=6 width=4)
Filter: (fld1 = 'VEND'::text)
-> Index Scan using i_T1_partial on T1 (cost=0.00..37.61
rows=8 width=8)
Index Cond: ((T1.prod_id = 42) AND (T1.fk1 = T2.fk1))

If those rowcount estimates are accurate, then this is a perfectly good
plan; in fact probably the best you could hope for.

regards, tom lane

Rowcounts seems to be quite accurate as the tables get "VACUUM FULL ANALYZE"d
regularly.
This query plan comes from index optimization.
It is the cost estimate for the nested loop that scares me a little.

As of now only file system caching seems to help the timing (by a factor 10)
but this in turn is a transitory effect as I have little control over FS
cache.

--
Fahrbahn ist ein graues Band
weisse Streifen, grüner Rand