Re: SELECT ... WHERE ... IN (SELECT ...) -> SELECT ... WHERE (... OR ... ) - Mailing list pgsql-ru-general

From Alexander M. Pravking
Subject Re: SELECT ... WHERE ... IN (SELECT ...) -> SELECT ... WHERE (... OR ... )
Date
Msg-id 20061204203159.GA61159@dyatel.antar.bryansk.ru
Whole thread Raw
In response to SELECT ... WHERE ... IN (SELECT ...) -> SELECT ... WHERE (... OR ... )  (Anton <anton200@gmail.com>)
Responses Re: SELECT ... WHERE ... IN (SELECT ...) -> SELECT ... WHERE (... OR ... )  (Anton <anton200@gmail.com>)
List 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

pgsql-ru-general by date:

Previous
From: Anton
Date:
Subject: Re: SELECT ... WHERE ... IN (SELECT ...) -> SELECT ... WHERE (... OR ... )
Next
From: Sergey Suleymanov
Date:
Subject: Re: SELECT ... WHERE ... IN (SELECT ...) ->