解決策
おそらく、解決策 演算子をスキーマ修飾することです:
SELECT *
FROM test
WHERE tagged OPERATOR(example@sqldat.com>) '{11}'::int2[]
ORDER BY id
LIMIT 100; なぜですか?
これはオペレーターの解決の問題です (タイプ解決とキャストコンテキストとの組み合わせ)
標準のPostgresでは、候補演算子anyarray @> anyarrayは1つだけです。 、それはあなたが望むものです。
追加のモジュールintarrayをインストールしていなければ、セットアップは問題なく機能します。 (私の仮定)、これはinteger[] @> integer[]の別の演算子を提供します 。
したがって、別の解決策はinteger[]を使用することです。 代わりに、gin__int_opsのGINインデックスを作成します 演算子クラス。または、(intarrayのデフォルト)gist__int_opsを試してください 索引。どちらかが速いかもしれませんが、どちらもNULL値を許可していません。
または、intarrayの名前を変更することもできます 演算子@> 明確にする。 (私はそうしません。アップグレードと移植性の問題が発生します。)
タイプinteger[]のオペランドを少なくとも1つ含む式の場合 、Postgresはどの演算子を選択するかを知っています:intarray演算子。ただし、インデックスは適用されません 、intarray演算子はintegerでのみ動作するため (int4 )int2ではありません 。また、インデックスは厳密に演算子にバインドされています:
- PostgreSQLは配列列にインデックスを付けることができますか?
- 同じ列に2つの異なるタイプのインデックスが存在する場合のPostgreSQLの動作
ただし、int2[] @> int2[]の場合 、Postgresは最適な演算子を決定できません。どちらも同じように適用できるようです。デフォルトの演算子はpg_catalogで提供されているため スキーマとintarray演算子は、publicで提供されます。 スキーマ(デフォルト-または拡張機能をインストールした場所)では、OPERATOR()を使用して演算子をスキーマ修飾することにより、難問を解決するのに役立ちます。 構築します。関連:
- 要素の順序を無視して、配列が等しいかどうかを比較します
表示されるエラーメッセージは少し誤解を招く可能性があります。しかし、よく見ると、HINTがあります。 正しい方向へのヒント(tada!)を追加した行:
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.
@>の既存の演算子候補を調査できます と:
SELECT o.oid, *, oprleft::regtype, oprright::regtype, n.nspname
FROM pg_operator o
JOIN pg_namespace n ON n.oid = o.oprnamespace
WHERE oprname = '@>';
別の代替ソリューションは、一時的に(!)別のsearch_pathを設定して、目的の演算子のみが見つかるようにすることです。同じトランザクションで:
SET LOCAL search_path = pg_catalog;
SELECT ...
ただし、クエリ内のすべてのテーブルをスキーマ修飾する必要があります。
キャストコンテキストについて:
- 一連の日付を生成します-入力として日付タイプを使用します
あなたはできた castcontextを変更します int2の -> int4 。しかし、私はそれに対して強くお勧めします。考えられる副作用が多すぎます:
- postgresql9.3データ型をキャストして片側だけに影響を与える方法はありますか