Saya tidak dapat menemukan jawaban yang pasti untuk pertanyaan ini dalam dokumentasi. Jika kolom adalah tipe array, apakah semua nilai yang dimasukkan akan diindeks secara individual?
Saya membuat tabel sederhana dengan satu int[]
kolom, dan meletakkan indeks unik di atasnya. Saya perhatikan bahwa saya tidak dapat menambahkan array int yang sama, yang membuat saya percaya bahwa indeks adalah gabungan dari item array, bukan indeks dari setiap item.
INSERT INTO "Test"."Test" VALUES ('{10, 15, 20}');
INSERT INTO "Test"."Test" VALUES ('{10, 20, 30}');
SELECT * FROM "Test"."Test" WHERE 20 = ANY ("Column1");
Apakah indeks membantu permintaan ini?
arrays
postgresql
indexing
IAMIC
sumber
sumber
jsonb
dan menggunakan indeks? postgresql.org/docs/9.5/static/functions-json.html dan postgresql.org/docs/9.5/static/datatype-json.html#JSON-INDEXINGJawaban:
Ya, Anda dapat mengindeks array, tetapi Anda harus menggunakan operator array dan tipe indeks GIN .
Contoh:
Hasil:
Catatantampaknya dalam banyak kasus opsi gin__int_ops diperlukan
Saya belum melihat kasus di mana ia akan bekerja dengan operator && dan @> tanpa opsi gin__int_ops
sumber
gin__int_ops
digunakan untukinteger[]
kolom. Butuh bertahun-tahun frustrasi dan mencari solusi lain sampai saya menemukan kelas op ini. Ini adalah pekerja mukjizat batas.@Tregoreg mengajukan pertanyaan dalam komentar untuk hadiah yang ditawarkannya:
@ Jawaban diterima Frank memberitahu Anda untuk menggunakan operator array , yang masih benar untuk Postgres 11. Manual:
Daftar lengkap kelas operator bawaan untuk indeks GIN dalam distribusi standar ada di sini.
Dalam indeks Postgres terikat ke operator (yang diterapkan untuk jenis tertentu), bukan tipe data saja atau fungsi atau apa pun. Itu adalah warisan dari desain Berkeley asli Postgres dan sangat sulit untuk diubah sekarang. Dan itu umumnya bekerja dengan baik. Berikut adalah utas tentang pgsql-bug dengan Tom Lane mengomentari ini.
Beberapa fungsi PostGis (seperti
ST_DWithin()
) tampaknya melanggar prinsip ini, tetapi tidak demikian. Fungsi-fungsi tersebut ditulis ulang secara internal untuk menggunakan masing-masing operator .Ekspresi yang diindeks harus di sebelah kiri operator. Untuk sebagian besar operator ( termasuk semua yang di atas ) perencana kueri dapat mencapai ini dengan membalik operan jika Anda menempatkan ekspresi yang diindeks ke kanan - mengingat bahwa
COMMUTATOR
telah ditentukan. TheANY
membangun dapat digunakan dalam kombinasi dengan berbagai operator dan tidak operator itu sendiri. Ketika digunakan sebagaiconstant = ANY (array_expression)
indeks saja yang mendukung=
operator pada elemen array akan memenuhi syarat dan kami akan membutuhkan komutator untuk= ANY()
. Indeks GIN keluar.Postgres saat ini tidak cukup pintar untuk mendapatkan ekspresi yang bisa diindeks GIN darinya. Sebagai permulaan,
constant = ANY (array_expression)
adalah tidak benar-benar setara denganarray_expression @> ARRAY[constant]
. Operator array mengembalikan kesalahan jika ada elemen NULL yang terlibat, sementaraANY
konstruk dapat menangani NULL di kedua sisi. Dan ada hasil yang berbeda untuk ketidakcocokan tipe data.Jawaban terkait:
Periksa apakah ada nilai dalam array Postgres
Indeks untuk menemukan elemen dalam array JSON
SQLAlchemy: bagaimana cara memfilter pada tipe kolom PgArray?
Bisakah IS DISTINCT FROM dikombinasikan dengan ANY atau ALL entah bagaimana?
Selain itu
Saat bekerja dengan
integer
array (int4
, bukanint2
atauint8
) tanpaNULL
nilai (seperti contoh Anda menyiratkan) pertimbangkan modul tambahanintarray
, yang menyediakan operator khusus, lebih cepat dan dukungan indeks. Lihat:Adapun
UNIQUE
kendala dalam pertanyaan Anda yang tidak dijawab: Itu diterapkan dengan indeks btree pada seluruh nilai array (seperti yang Anda duga) dan tidak membantu dengan pencarian elemen sama sekali. Detail:sumber
gin__int_ops
digunakan untukinteger[]
kolom. Butuh bertahun-tahun frustrasi dan mencari solusi lain sampai saya menemukan kelas op ini. Ini adalah pekerja mukjizat batas.ANY (array_expression) = constant
ekspresi, indeks GIN berfungsi dengan baik?Sekarang mungkin untuk mengindeks elemen array individual. Sebagai contoh:
Ini berfungsi setidaknya pada Postgres 9.2.1. Perhatikan bahwa Anda perlu membuat indeks terpisah untuk setiap indeks array, dalam contoh saya, saya hanya mengindeks elemen pertama.
sumber