Re: SELECT ... WHERE ... IN (SELECT ...) -> SELECT ... WHERE (... OR ... ) - Mailing list pgsql-ru-general
From | Anton |
---|---|
Subject | Re: SELECT ... WHERE ... IN (SELECT ...) -> SELECT ... WHERE (... OR ... ) |
Date | |
Msg-id | 8cac8dd0612042247i4185ce35xd2952791f726b005@mail.gmail.com Whole thread Raw |
In response to | Re: SELECT ... WHERE ... IN (SELECT ...) -> SELECT ... WHERE (... OR ... ) ("Alexander M. Pravking" <fduch@antar.bryansk.ru>) |
Responses |
Re: SELECT ... WHERE ... IN (SELECT ...) -> SELECT ... WHERE (... OR ... )
("Alexander M. Pravking" <fduch@antar.bryansk.ru>)
|
List | pgsql-ru-general |
Может с этого надо было начать... Словом, потребность есть ВЫБРАТЬ ПОСЛЕДНЮЮ ДАТУ (поле collect_time) ИЗ ТАБЛИЦЫ ТРАФИКА (таблица n_traffic) ДЛЯ ВСЕХ ЛОГИНОВ (поле login_id) ЗАДАННОГО АККАУНТА (поле account_id). То есть из таблицы n_logins выбрать все login_id которые имеют заданный account_id, а потом из таблицы n_traffic выбрать самую последнюю дату из всех этих login_id. PostgreSQL 8.1.5. > Здесь явно неразумный план: выборка из большой таблицы всех (видимо) > записей по условию, которое всегда true. Здесь даже seq scan был бы > быстрее (ANALYZE давно делали?). VACUUM FULL ANALYZE делался буквально перед тем как. collect_time НЕ ВСЕГДА сравнивается с "1970-01-01 ...", а более чаще с датой начала текущего месяца. Но в определенных случаях (некоторые данные неизвестны) берется просто тот самый "1970-01-01 ...". Однако это дела не меняет, если даже убрать вообще условие с collect_time (см. планы внизу для nestloop ON и OFF). > На мой взгляд, как раз вариант, который предложил Фёдор, должен > использовать более приемлемый join. Можно взглянуть на его EXPLAIN? ... > порядок JOIN'а вручную. Насчёт восьмёрки вроде проскакивало, что > оптимизатор умничает даже в случае явного JOIN, хотя я не уверен, так > что можно попробовать и этот вариант. см. ниже, видимо это как раз то, о чём ты говоришь. set enable_nestloop=off; =# explain analyze SELECT billing-# collect_time billing-# FROM billing-# n_traffic, billing-# n_logins billing-# WHERE billing-# n_traffic.login_id = n_logins.login_id billing-# AND billing-# account_id = '1655' billing-# order by collect_time limit 1; ---------------------------------------- Limit (cost=6248.14..6248.14 rows=1 width=8) (actual time=1473.737..1473.737 rows=0 loops=1) -> Sort (cost=6248.14..6249.21 rows=430 width=8) (actual time=1473.732..1473.732 rows=0 loops=1) Sort Key: n_traffic.collect_time -> Hash Join (cost=3.54..6229.33 rows=430 width=8) (actual time=1473.695..1473.695 rows=0 loops=1) Hash Cond: ("outer".login_id = "inner".login_id) -> Seq Scan on n_traffic (cost=0.00..4861.66 rows=271966 width=12) (actual time=0.015..804.507 rows=272007 loops=1) -> Hash (cost=3.53..3.53 rows=2 width=4) (actual time=0.078..0.078 rows=2 loops=1) -> Index Scan using n_logins_account_id on n_logins (cost=0.00..3.53 rows=2 width=4) (actual time=0.033..0.045 rows=2 loops=1) Index Cond: (account_id = 1655) Total runtime: 1474.019 ms (10 rows) set enable_nestloop=on; =# explain analyze SELECT billing-# collect_time billing-# FROM billing-# n_traffic, billing-# n_logins billing-# WHERE billing-# n_traffic.login_id = n_logins.login_id billing-# AND billing-# account_id = '1655' billing-# order by collect_time limit 1; ---------------------------------------- Limit (cost=0.00..2026.44 rows=1 width=8) (actual time=6280.321..6280.321 rows=0 loops=1) -> Nested Loop (cost=0.00..871369.04 rows=430 width=8) (actual time=6280.315..6280.315 rows=0 loops=1) -> Index Scan using n_traffic_collect_time_login_id on n_traffic (cost=0.00..10352.51 rows=271966 width=12) (actual time=0.029..1267.549 rows=272007 loops=1) -> Index Scan using n_logins_pkey on n_logins (cost=0.00..3.15 rows=1 width=4) (actual time=0.012..0.012 rows=0 loops=272007) Index Cond: ("outer".login_id = n_logins.login_id) Filter: (account_id = 1655) Total runtime: 6280.565 ms -- engineer
pgsql-ru-general by date: