Re: SELECT ... WHERE ... IN (SELECT ...) -> SELECT ... WHERE (... OR ... )

From: "Alexander M(dot) Pravking" <fduch(at)antar(dot)bryansk(dot)ru>
To: Anton <anton200(at)gmail(dot)com>
Cc: pgsql-ru-general(at)postgresql(dot)org
Subject: Re: SELECT ... WHERE ... IN (SELECT ...) -> SELECT ... WHERE (... OR ... )
Date: 2006-12-04 20:31:59
Message-ID: 20061204203159.GA61159@dyatel.antar.bryansk.ru
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-ru-general

On Mon, 2006-12-04 at 21:24 +0500, Anton wrote:
> Подробности:
> SELECT collect_time FROM n_traffic WHERE collect_time > '1970-01-01
> 00:00:00'
> AND login_id IN (SELECT login_id FROM n_logins WHERE account_id = '1655')
> ORDER BY collect_time LIMIT 1
> --------------------------------
> Limit (cost=0.00..2028.44 rows=1 width=8) (actual
> time=4434.532..4434.532 rows=0 loops=1)
> -> Nested Loop IN Join (cost=0.00..722123.09 rows=356 width=8)
> (actual time=4434.527..4434.527 rows=0 loops=1)
> -> Index Scan using n_traffic_collect_time on n_traffic
> (cost=0.00..9723.29 rows=225023 width=12) (actual time=0.036..830.414
> rows=224971 loops=1)
> Index Cond: (collect_time > '1970-01-01
> 00:00:00'::timestamp without time zone)

Здесь явно неразумный план: выборка из большой таблицы всех (видимо)
записей по условию, которое всегда true. Здесь даже seq scan был бы
быстрее (ANALYZE давно делали?).

> -> Index Scan using n_logins_pkey on n_logins
> (cost=0.00..3.15 rows=1 width=4) (actual time=0.010..0.010 rows=0
> loops=224971)

Далее по всем этим найденным записям прогоняется поиск в n_logins.
Поиск сам по себе быстрый, но много-многократный. В итоге
Nested Loop IN Join выше выполняется уже 4 секунды.

> Index Cond: ("outer".login_id = n_logins.login_id)
> Filter: (account_id = 1655)
> Total runtime: 4434.827 ms
> (8 rows)

На мой взгляд, как раз вариант, который предложил Фёдор, должен
использовать более приемлемый join. Можно взглянуть на его EXPLAIN?

И, кстати, во времена семёрки рекомендовалось использовать JOIN в явном
виде, когда оптимизатор выбирал не лучший вариант, то есть задавать
порядок JOIN'а вручную. Насчёт восьмёрки вроде проскакивало, что
оптимизатор умничает даже в случае явного JOIN, хотя я не уверен, так
что можно попробовать и этот вариант.

--
Fduch M. Pravking

In response to

Responses

Browse pgsql-ru-general by date

  From Date Subject
Next Message Sergey Suleymanov 2006-12-05 06:31:13 Re: SELECT ... WHERE ... IN (SELECT ...) ->
Previous Message Anton 2006-12-04 18:17:54 Re: SELECT ... WHERE ... IN (SELECT ...) -> SELECT ... WHERE (... OR ... )