PostgreSQL
 sql >> Teknologi Basis Data >  >> RDS >> PostgreSQL

Indeks GIN pada kolom smallint[] tidak digunakan atau operator kesalahan tidak unik

Solusi

Kemungkinan besar, solusi adalah untuk memenuhi syarat skema operator:

SELECT *
FROM   test
WHERE  tagged OPERATOR([email protected]>) '{11}'::int2[]
ORDER  BY id
LIMIT  100;

Mengapa?

Ini masalah resolusi operator (dikombinasikan dengan resolusi jenis dan konteks pemeran).

Di Postgres standar, hanya ada satu kandidat operator anyarray @> anyarray , itu yang Anda inginkan.

Penyiapan Anda akan berfungsi dengan baik jika Anda tidak memasang intarray modul tambahan (asumsi saya), yang menyediakan operator lain untuk integer[] @> integer[] .

Oleh karena itu, solusi lain adalah menggunakan integer[] sebagai gantinya dan memiliki indeks GIN dengan gin__int_ops kelas operator. Atau coba (default untuk intarray) gist__int_ops indeks. Mungkin lebih cepat, tetapi keduanya tidak mengizinkan nilai NULL.
Atau Anda dapat mengganti nama intarray operator @> untuk disambiguasi. (Saya tidak akan melakukannya. Masalah peningkatan dan portabilitas terjadi.)

Untuk ekspresi yang melibatkan setidaknya satu operan bertipe integer[] , Postgres tahu operator mana yang harus dipilih:operator intarray. Tapi kemudian indeks tidak berlaku , karena operator intarray hanya beroperasi pada integer (int4 ) bukan int2 . Dan indeks sangat terikat dengan operator:

  • Dapatkah PostgreSQL mengindeks kolom array?
  • Perilaku PostgreSQL dengan adanya dua jenis indeks yang berbeda pada kolom yang sama

Tapi untuk int2[] @> int2[] , Postgres tidak dapat menentukan operator terbaik. Keduanya tampak sama-sama berlaku. Karena operator default disediakan di pg_catalog skema dan operator intarray disediakan di public schema (secara default - atau di mana pun Anda memasang ekstensi), Anda dapat membantu memecahkan teka-teki dengan membuat operator memenuhi syarat skema dengan OPERATOR() membangun. Terkait:

  • Bandingkan array untuk kesetaraan, abaikan urutan elemen

Pesan kesalahan yang Anda dapatkan agak menyesatkan. Tetapi jika Anda perhatikan lebih dekat, ada HINT baris menambahkan petunjuk mana (tada!) ke arah yang benar:

ERROR:  operator is not unique: smallint[] @> smallint[]
LINE 1: SELECT NULL::int2[] @> NULL::int2[]
                            ^
HINT:  Could not choose a best candidate operator. You might need to add explicit type casts.

Anda dapat menyelidiki kandidat operator yang ada untuk @> dengan:

SELECT o.oid, *, oprleft::regtype, oprright::regtype, n.nspname
FROM   pg_operator o
JOIN   pg_namespace n ON n.oid = o.oprnamespace
WHERE  oprname = '@>';

Solusi alternatif lain adalah untuk sementara(!) menyetel search_path yang berbeda, jadi hanya operator yang diinginkan yang ditemukan. Dalam transaksi yang sama:

SET LOCAL search_path = pg_catalog;
SELECT ...

Namun kemudian Anda harus membuat skema-kualifikasi semua tabel dalam kueri.

Tentang konteks pemeran:

  • Buat rangkaian tanggal - menggunakan jenis tanggal sebagai masukan

Anda bisa ubah castcontext dari int2 -> int4 . Tapi saya sangat menyarankan untuk tidak melakukannya. Terlalu banyak kemungkinan efek samping:

  • Apakah ada cara untuk mentransmisikan tipe data postgresql 9.3 sehingga hanya dapat mempengaruhi satu sisi



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Bagaimana cara menampilkan nomor baris dalam kueri PostgreSQL?

  2. KESALAHAN:string kutipan yang tidak diakhiri pada atau di dekat

  3. Rails 3.1:Meminta Postgres untuk catatan dalam rentang waktu

  4. Menulis file menggunakan banyak utas

  5. Cara mendapatkan daftar parameter fungsi (sehingga saya bisa menjatuhkan fungsi)