Pot't găsi un răspuns clar la această întrebare în documentație. Dacă o coloană este o matrice de tip, va toate valorile introduse individual indexate?
Am creat un tabel simplu cu unul int[]
de coloană, și a pus un index unic pe ea. Am observat ca nu puteam't adăuga același tablou de int, ceea ce mă face să cred că indicele este un compozit de matrice de elemente, nu un indice al fiecărui element.
INSERT INTO "Test"."Test" VALUES ('{10, 15, 20}');
INSERT INTO "Test"."Test" VALUES ('{10, 20, 30}');
SELECT * FROM "Test"."Test" WHERE 20 = ANY ("Column1");
Este indicele ajuta această interogare?
Da, se poate indexa o matrice, dar va trebui să utilizați matrice operatorilor și GIN-tip index.
Exemplu:
CREATE TABLE "Test"("Column1" int[]);
INSERT INTO "Test" VALUES ('{10, 15, 20}');
INSERT INTO "Test" VALUES ('{10, 20, 30}');
CREATE INDEX idx_test on "Test" USING GIN ("Column1");
-- To enforce index usage because we have only 2 records for this test...
SET enable_seqscan TO off;
EXPLAIN ANALYZE
SELECT * FROM "Test" WHERE "Column1" @> ARRAY[20];
Rezultatul:
Bitmap Heap Scan on "Test" (cost=4.26..8.27 rows=1 width=32) (actual time=0.014..0.015 rows=2 loops=1)
Recheck Cond: ("Column1" @> '{20}'::integer[])
-> Bitmap Index Scan on idx_test (cost=0.00..4.26 rows=1 width=0) (actual time=0.009..0.009 rows=2 loops=1)
Index Cond: ("Column1" @> '{20}'::integer[])
Total runtime: 0.062 ms
se pare că, în multe cazuri, gin__int_ops opțiune este necesară
create index <index_name> on <table_name> using GIN (<column> gin__int_ops)
Încă nu am văzut un caz în care s-ar lucra cu && iar @> operator fără gin__int_ops opțiuni
@Tregoreg ridicat o intrebare în comentariul său a oferit recompense:
nu am't găsi răspunsurile actuale de lucru. Folosind GIN index pe array-introduce coloana nu crește performanța de ORICE() operator. Există într-adevăr nici o soluție?
@Frank's acceptate raspuns spune să utilizați matrice operatorii, care este corect pentru Postgres 11. Manualul:
... distributia standard de PostgreSQL include un GIN operator clasa de tablouri, care sprijină indexate interogări folosind aceste operatori:
<@ @>
&&
În Postgres indici sunt obligate să operatori (care sunt puse în aplicare pentru anumite tipuri), nu tipuri de date singur sau funcții sau orice altceva. Ca's a patrimoniului de original Berkeley design de Postgres și foarte greu să se schimbe acum. Și-l's, în general, funcționează foarte bine. Aici este un thread pe pgsql-bug-uri cu Tom Lane comentând acest lucru.
Unele PostGis funcții (cum ar fi ST_DWithin()
) pare să încalce acest principiu, dar că nu este așa. Aceste funcții sunt rescrise pe plan intern pentru a utiliza respective operatori.
Indexate exprimare trebuie să fie a plecat de operator. Pentru majoritatea operatorilor (inclusiv toate cele de mai sus) interogarea planificatorul poate realiza acest lucru prin flipping operanzi, dacă ai loc indexate exprimare a dreptului - având în vedere că o COLECTOR
a fost definit. A ORICE
construi pot fi utilizate în combinație cu diverși operatori și nu este un operator de la sine. Atunci când este utilizat ca "constant" = ORICE (array_expression)doar indicii care sprijină
=operator pe *elementele de matrice* s-ar califica si vom avea nevoie de un comutator pentru
= ORICE()`. GIN indici sunt afară.
Postgres în prezent nu este suficient de inteligent pentru a obține un GIN-indexabile expresie de la ea. Pentru început, constant = ORICE (array_expression)e **nu sunt complet echivalente** a
array_expression @> MATRICE[constantă]`. Matrice operatorii returna o eroare dacă orice NUL elemente sunt implicate, în timp ce "ORICE" construct poate face cu NUL pe fiecare parte. Și există rezultate diferite pentru date de tip nepotriviri.
Legate de răspunsuri:
În timp ce lucrează cu "număr întreg" tablouri (int4", nu "int2" sau " int8
) fără NULL
valori (ca exemplu presupune) ia în considerare modul suplimentar intarray
, care oferă de specialitate, mai repede operatorii și indicele de sprijin. A se vedea:
Pentru ca "UNIC" constrângere în cauză că au rămas fără răspuns: Care's implementată cu un btree index pe gamă întreagă valoare (ca tine suspectate) si nu ajuta cu căutare elemente la toate. Detalii:
L's acum posibil să se indice individuale elementele de matrice. De exemplu:
CREATE TABLE test (foo int[]);
INSERT INTO test VALUES ('{1,2,3}');
INSERT INTO test VALUES ('{4,5,6}');
CREATE INDEX test_index on test ((foo[1]));
SET enable_seqscan TO off;
EXPLAIN ANALYZE SELECT * from test WHERE foo[1]=1;
QUERY PLAN
------------------------------------------------------------------------------------------------------------------
Index Scan using test_index on test (cost=0.00..8.27 rows=1 width=32) (actual time=0.070..0.071 rows=1 loops=1)
Index Cond: (foo[1] = 1)
Total runtime: 0.112 ms
(3 rows)
Acest lucru funcționează cel puțin Postgres 9.2.1. Rețineți că aveți nevoie pentru a construi un index separat pentru fiecare indice matrice, în exemplul meu am indexate doar primul element.