2016-03-22 10 views
0

ich wählen auf Postgres Tisch ein interessanter Fall haben:PostgreSQL-Optimierung: Sequantial Scan VS Index Scan

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

Hier ist meine select:

select count(*) from advert where user_id in USER_IDS_ARRAY 

Und wenn USER_IDS_ARRAY Länge < = 100 Ich habe Als nächstes erklären zu analysieren:

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 

Aber wenn USER_IDS_ARRAY Länge> 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 

Egal, was in USER_IDS_ARRAY benutzerkennungen, nur ihre Gesamtlänge zählt.

Hat jemand Ideen, wie man dies optimieren kann für mehr als 100 user_ids auswählen?

+0

Haben Sie versucht, nur aus "advert" ohne den Beitritt zu wählen? Filtern Sie mit> 100 Benutzer-IDs und prüfen Sie, ob der Index verwendet wird oder nicht. – Sevanteri

+0

@Sevanteri ja, du hast Recht, die gleiche Situation mit der Anzeige auswählen. Vereinfachte meine Frage nur mit einer Tabelle. –

+0

Rechts. Es scheint, dass der Abfrageplaner nur denkt, dass es besser ist, stattdessen einen Seq-Scan durchzuführen. Sie könnten [analyse'] (http://www.postgresql.org/docs/current/static/sql-analyze.html) für die Tabellen ausführen und sehen, ob es hilft. – Sevanteri

Antwort

3

Wenn SET enable_seqscan = OFF den Index-Scan immer noch nicht erzwingt, bedeutet dies, dass der Index-Scan nicht möglich ist. Es stellt sich heraus, dass der Index hier partiell war.