W dokumentacji nie mogę znaleźć jednoznacznej odpowiedzi na to pytanie. Jeśli kolumna jest typem tablicowym, czy wszystkie wprowadzone wartości będą indeksowane indywidualnie?
Stworzyłem prostą tabelę z jedną int[]
kolumną i umieściłem na niej unikalny indeks. Zauważyłem, że nie mogłem dodać tej samej tablicy liczb int, co prowadzi mnie do przekonania, że indeks jest złożeniem elementów tablicy, a nie indeksem każdego elementu.
INSERT INTO "Test"."Test" VALUES ('{10, 15, 20}');
INSERT INTO "Test"."Test" VALUES ('{10, 20, 30}');
SELECT * FROM "Test"."Test" WHERE 20 = ANY ("Column1");
Czy indeks pomaga w tym zapytaniu?
arrays
postgresql
indexing
IamIC
źródło
źródło
jsonb
i indeksów? postgresql.org/docs/9.5/static/functions-json.html i postgresql.org/docs/9.5/static/datatype-json.html#JSON-INDEXINGOdpowiedzi:
Tak, możesz indeksować tablicę, ale musisz użyć operatorów tablic i typu indeksu GIN .
Przykład:
Wynik:
Uwagawydaje się, że w wielu przypadkach opcja gin__int_ops jest wymagana
Nie widziałem jeszcze przypadku, w którym działałoby to z operatorem && i @> bez opcji gin__int_ops
źródło
gin__int_ops
są używane dlainteger[]
kolumn. Zajęło mi lata frustracji i szukania innych rozwiązań, zanim odkryłem tę klasę operacyjną. To cudotwórca z pogranicza.@Tregoreg zadał pytanie w komentarzu do swojej oferowanej nagrody:
Zaakceptowana odpowiedź @ Franka mówi, że należy używać operatorów tablicowych , co nadal jest poprawne dla Postgres 11. Podręcznik:
Pełna lista wbudowanych klas operatorów dla indeksów GIN w standardowej dystrybucji znajduje się tutaj.
W Postgres indeksy są powiązane z operatorami (które są zaimplementowane dla pewnych typów), a nie z samymi typami danych, funkcjami czy czymkolwiek innym. To dziedzictwo oryginalnego projektu Postgres Berkeley i bardzo trudne do zmiany. I ogólnie działa dobrze. Tutaj jest wątek na temat pgsql-bugs z komentarzem Tom'a Lane'a.
Niektóre funkcje PostGis (takie jak
ST_DWithin()
) wydają się naruszać tę zasadę, ale tak nie jest. Te funkcje są przepisywane wewnętrznie, aby używać odpowiednich operatorów .Indeksowane wyrażenie musi znajdować się po lewej stronie operatora. W przypadku większości operatorów (w tym wszystkich powyższych ) planista zapytań może to osiągnąć, odwracając operandy, jeśli umieścisz indeksowane wyrażenie po prawej stronie - zakładając, że
COMMUTATOR
zdefiniowano a.ANY
Konstrukt może być stosowany w połączeniu z różnych operatorów i nie jest sama w sobie operatora. Gdy jest używany jakoconstant = ANY (array_expression)
tylko indeksy obsługujące=
operator na elementach tablicy , kwalifikowałby się i potrzebowalibyśmy komutatora= ANY()
. Indeksy GIN są wyłączone.Postgres nie jest obecnie wystarczająco inteligentny, aby wyprowadzić z niego wyrażenie indeksowalne GIN. Na początek nie
constant = ANY (array_expression)
jest całkowicie równoważne zarray_expression @> ARRAY[constant]
. Operatory tablicowe zwracają błąd, jeśli zaangażowane są jakiekolwiek elementy NULL , podczas gdyANY
konstrukcja może obsłużyć NULL po obu stronach. Istnieją różne wyniki dla niezgodności typów danych.Powiązane odpowiedzi:
Sprawdź, czy wartość istnieje w tablicy Postgres
Indeks do znajdowania elementu w tablicy JSON
SQLAlchemy: jak filtrować według typów kolumn PgArray?
Czy JEST WYRÓŻNIONY OD JAKIEKOLWIEK lub WSZYSTKIE?
Poza tym
Podczas pracy z
integer
tablicami (int4
nieint2
lubint8
) bezNULL
wartości (jak sugeruje twój przykład) rozważ dodatkowy modułintarray
, który zapewnia wyspecjalizowane, szybsze operatory i obsługę indeksów. Widzieć:Jeśli chodzi o
UNIQUE
ograniczenie w twoim pytaniu, które pozostało bez odpowiedzi: jest zaimplementowane z indeksem btree na całej wartości tablicy (tak jak podejrzewasz) i wcale nie pomaga w wyszukiwaniu elementów . Detale:źródło
gin__int_ops
są używane dlainteger[]
kolumn. Zajęło mi lata frustracji i szukania innych rozwiązań, zanim odkryłem tę klasę operacyjną. To cudotwórca z pogranicza.ANY (array_expression) = constant
wyrażeń indeksy GIN działają dobrze?Teraz można indeksować poszczególne elementy tablicy. Na przykład:
Działa to przynajmniej na Postgres 9.2.1. Zauważ, że musisz zbudować oddzielny indeks dla każdego indeksu tablicy, w moim przykładzie zindeksowałem tylko pierwszy element.
źródło