2016-03-22 5 views
0

У меня есть один интересный случай с отборным на Postgres таблице:PostgreSQL оптимизация: Sequantial Scan VS Index Scan

advert (~2.5 million records) 
    id serial, 
    user_id integer (foreign key), 
    ... 

Вот мой выбор:

select count(*) from advert where user_id in USER_IDS_ARRAY 

И если USER_IDS_ARRAY длина < = 100 У меня есть следующий объяснить проанализировать:

Aggregate (cost=18063.36..18063.37 rows=1 width=0) (actual time=0.362..0.362 rows=1 loops=1) 
    -> Index Only Scan using ix__advert__user_id on advert (cost=0.55..18048.53 rows=5932 width=0) (actual time=0.030..0.351 rows=213 loops=1) 
     Index Cond: (user_id = ANY ('{(...)}')) 
     Heap Fetches: 213 
Planning time: 0.457 ms 
Execution time: 0.392 ms 

Но когда USER_IDS_ARRAY длина> 100:

Aggregate (cost=424012.09..424012.10 rows=1 width=0) (actual time=867.438..867.438 rows=1 loops=1) 
    -> Seq Scan on advert (cost=0.00..423997.11 rows=5992 width=0) (actual time=0.375..867.345 rows=213 loops=1) 
     Filter: (user_id = ANY ('{(...)}')) 
     Rows Removed by Filter: 2201318 
Planning time: 0.261 ms 
Execution time: 867.462 ms 

Независимо от того, что user_ids в USER_IDS_ARRAY, только это вопросы, длины.

Есть ли у кого-нибудь идеи, как оптимизировать этот выбор для более 100 пользовательских_пользователей?

+0

Вы пробовали просто выбрать «объявление» без участия? Фильтр с> 100 идентификаторами пользователей и посмотрите, использует ли он индекс или нет. – Sevanteri

+0

@Sevanteri да, вы правы, такая же ситуация с рекламой. Упростил мой вопрос только одной таблицей. –

+0

Справа. Похоже, что планировщик запросов просто думает, что лучше делать сканирование seq. Вы можете запустить ['анализ'] (http://www.postgresql.org/docs/current/static/sql-analyze.html) для таблиц и посмотреть, помогает ли это. – Sevanteri

ответ

3

Если SET enable_seqscan = OFF все еще не принудительно сканирует индекс, это означает, что сканирование индекса невозможно. Оказывается, индекс был частичным.