2013-08-15 10 views
7

Wir haben eine Tabelle mit einem indizierten Array Spalte:Kann sich das Postgres-Array überlappen (&&) operator einen Index verwenden?

CREATE TABLE mention (
    id SERIAL, 
    phraseIds integer[], 
    PRIMARY KEY (id) 
); 
CREATE INDEX indx_mentions_phraseIds on mention USING GIN (phraseids public.gin__int_ops); 

Abfragen des „überlappt“ Operator auf dieser Spalte scheint nicht, den Index zu verwenden:

explain analyze select m.id FROM mention m WHERE m.phraseIds && ARRAY[11638,11639]; 

Seq Scan on mention m (cost=0.00..933723.44 rows=1404 width=4) (actual time=103.018..3751.525 rows=1101 loops=1) 
Filter: (phraseids && '{11638,11639}'::integer[]) 
Rows Removed by Filter: 7019974 
Total runtime: 3751.618 ms 

Ist es möglich, zu erhalten Postgresql den Index zu verwenden? Oder sollten wir etwas anderes machen?

Update: Ich habe den Test mit 'SET enable_seqscan TO off' wiederholt und der Index wird immer noch nicht verwendet.

Update: Ich hätte erwähnen sollen, dass ich 9.2 mit der Intarray-Erweiterung verwende.

Update: Es scheint, dass die Intarray-Erweiterung Teil dieses Problems ist. Ich habe die Tabelle neu erstellt, ohne die Intarray-Erweiterung zu verwenden, und der Index wird wie erwartet verwendet. Wer weiß, wie der Index für die Intarray-Erweiterung verwendet wird? Die Dokumente (http://www.postgresql.org/docs/9.2/static/intarray.html) sagen, dass Indizes für & & unterstützt werden.

+1

Verwenden Sie 'SET enable_seqscan TO off' und sehen Sie zuerst, ob PG * den Index verwenden kann, sollte es, und dann, wenn der Index-Scan schneller als der Seq-Scan sein wird. Veröffentlichen Sie das Ergebnis bitte hier. – MatheusOl

+0

Warum speichert ein * Array * von ID-Nummern in jeder Zeile das beste Design für Ihre Tabelle? –

+0

Die Daten waren zuvor in MySQL und wir verwendeten eine Reihe von separaten Spalten (Phrase0, Phrase1, ...), um die Daten zu halten. Die Verwendung einer separaten Tabelle war sehr langsam auf MySQL (viele Millionen Zeilen in beiden Tabellen und wir müssen das Ergebnis sortieren und begrenzen). Die Verwendung eines Postgres-Arrays schien eine gute Sache zu sein. –

Antwort

3

Ich baute eine ähnliche Tabelle in PostgreSQL 9.2; der Unterschied war USING GIN (phraseids); Ich habe nicht Int_ops in diesem Zusammenhang aus irgendeinem Grund zur Verfügung. Ich habe ein paar tausend Reihen von zufälligen (ish) Daten geladen.

Die Einstellung enable_seqscan off lässt PostgreSQL den Index verwenden.

PostgreSQL hat die Kosten eines sequenziellen Scans so berechnet, dass sie unter den Kosten eines Bitmap-Heap-Scans liegen. Die tatsächliche Zeit eines sequenziellen Scans betrug 10% der tatsächlichen Zeit eines Bitmap-Heap-Scans, aber die Gesamtlaufzeit für einen sequenziellen Scan war ein wenig mehr als die gesamte Laufzeit eines Bitmap-Heap-Scans.

+0

Ok. Wenn Sie die Intarray-Erweiterung des Index für diese Spalte nicht verwenden, wird sie aussortiert. Das werden wir für jetzt tun. Tx. –

Verwandte Themen