sql >> Database >  >> RDS >> PostgreSQL

GIN-index op smallint[]-kolom niet gebruikt of foutoperator is niet uniek

Oplossing

Hoogstwaarschijnlijk de oplossing is om de operator schema-kwalificeren:

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

Waarom?

Het is een probleem van operatorresolutie (in combinatie met typeresolutie en cast-context).

In standaard Postgres is er slechts één kandidaat-operator anyarray @> anyarray , dat is degene die je wilt.

Je setup zou prima werken als je de extra module intarray niet had geïnstalleerd (mijn aanname), die een andere operator biedt voor integer[] @> integer[] .

Daarom zou een andere oplossing zijn om integer[] . te gebruiken in plaats daarvan en een GIN-index hebben met de gin__int_ops operator klasse. Of probeer de (standaard voor intarray) gist__int_ops inhoudsopgave. Beide kunnen sneller zijn, maar beide staan ​​geen NULL-waarden toe.
Of u kunt de naam van de intarray wijzigen operator @> ondubbelzinnig te maken. (Dat zou ik niet doen. Upgrade- en draagbaarheidsproblemen treden op.)

Voor uitdrukkingen met ten minste één operand van het type integer[] , Postgres weet welke operator hij moet kiezen:de intarray-operator. Maar dan is de index niet van toepassing , omdat de intarray-operator alleen werkt op integer (int4 ) niet int2 . En indexen zijn strikt gebonden aan operators:

  • Kunnen PostgreSQL matrixkolommen indexeren?
  • PostgreSQL-gedrag in aanwezigheid van twee verschillende typen indexen in dezelfde kolom

Maar voor int2[] @> int2[] , Postgres kan niet beslissen wat de beste operator is. Beide lijken even toepasselijk. Aangezien de standaardoperator is opgegeven in de pg_catalog schema en de intarray-operator wordt gegeven in de public schema (standaard - of waar u de extensie ook hebt geïnstalleerd), kunt u het raadsel helpen oplossen door de operator schema-kwalificatie te geven met de OPERATOR() bouwen. Gerelateerd:

  • Vergelijk arrays voor gelijkheid, negeer de volgorde van elementen

De foutmelding die je krijgt is een beetje misleidend. Maar als je goed kijkt, is er een HINT regel toegevoegd die hints (tada!) in de goede richting:

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.

U kunt bestaande operatorkandidaten onderzoeken voor @> met:

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

Een andere alternatieve oplossing zou zijn om tijdelijk(!) een ander zoekpad in te stellen, zodat alleen de gewenste operator wordt gevonden. In dezelfde transactie:

SET LOCAL search_path = pg_catalog;
SELECT ...

Maar dan moet je alle tabellen in de query schema-kwalificeren.

Over cast-context:

  • Genereer een reeks datums - gebruik het datumtype als invoer

Je zou verander de castcontext van int2 -> int4 . Maar ik raad het ten zeerste af. Te veel mogelijke bijwerkingen:

  • Is er een manier om het postgresql 9.3-gegevenstype te casten, zodat het slechts één kant kan beïnvloeden



  1. Hoe gebruik je afbeeldingen in Android SQLite die groter zijn dan de beperkingen van een CursorWindow?

  2. Kan niet bulksgewijs laden. Besturingssysteem foutcode 5 (Toegang is geweigerd.)

  3. MySQL-tijdzones

  4. Hoe kan ik een dynamische WHERE-clausule maken?