1

Like to match starts の代わりに使用できる他のソリューションはありますか?

これは、like を使用して開始する一致するクエリです。

explain analyze select * from completedcalls where call_id like 'GWYA4NvSLzoIcvA7RAtmn_a9IelwOQeH@209.44.103.3%';
                                                    QUERY PLAN                                                    
------------------------------------------------------------------------------------------------------------------
 Seq Scan on completedcalls  (cost=0.00..52659.96 rows=112 width=228) (actual time=1.541..249.857 rows=2 loops=1)
   Filter: ((call_id)::text ~~ 'GWYA4NvSLzoIcvA7RAtmn_a9IelwOQeH@209.44.103.3%'::text)
 Total runtime: 249.893 ms
(3 rows)

これは、インデックス スキャンの代わりにシーケンス スキャンを行うため、非常に拡張性があります。like の性質上、提供された列にインデックスを使用することはできません。列のインデックスは次のように単純です。

"i_call_id" btree (call_id)

likeを使用せずに速度を向上させるのに役立つ特別なクラスのインデックス、またはlikeを使用せずに同じことを達成する他の方法はありますか?

使用されるテーブル スクリプトは次のとおりです。

              Table "public.completedcalls"
    Column     |           Type           |  Modifiers   
---------------+--------------------------+--------------
 call_id       | character varying(128)   | 
 sip_code      | integer                  | 
 duration      | integer                  | 
 setup_time    | timestamp with time zone | not null
 authname      | character varying(30)    | 
 src_sig_ip    | character varying(20)    | 
 dst_sig_ip    | character varying(20)    | 
 cld           | character varying(22)    | 
 cli           | character varying(22)    | 
Indexes:
    "i_call_id" btree (call_id)
    "i_dst_sig_ip" btree (dst_sig_ip)
4

5 に答える 5

3

このLIKEインデックスの使用 (またはその欠如) のケースは、ドキュメントで説明されています。

つまり、次のようにインデックスを作成する必要があります

create index i_call_id on completedcalls(call_id varchar_pattern_ops);

ただし、注意事項については、上記のリンク先のページをお読みください。

于 2013-01-15T20:48:53.183 に答える
2

LIKE先頭のワイルドカードがないと仮定すると、ステートメントは引き続き b ツリー インデックスで使用できます。

オプティマイザーは、パターン マッチング演算子を含むクエリに B ツリー インデックスを使用することもできます。また、パターンが定数であり、文字列の先頭にアンカーされている場合LIKEは ~ を使用できます。col LIKE 'foo%'col ~ '^foo'col LIKE '%bar'

インデックスが使用されていない場合は、ここに示されている使用法以外の理由がありLIKEます...

于 2013-01-15T20:42:23.877 に答える
1

パフォーマンスに役立つかどうかはわかりませんが、正規表現の使用について調べましたか? キャレット^を使用して、文字列の先頭にあるレコードを返すことができます。

多分このようなもの:

select * 
from completedcalls 
where call_id ~ '^GWYA4NvSLzoIcvA7RAtmn_a9IelwOQeH@209.44.103.3';
于 2013-01-15T20:42:14.877 に答える
1

LIKE末尾に がある条件でインデックスを使用できます%

オプティマイザーは、フル スキャンがインデックス スキャンよりも優れていると判断する可能性があります。インデックス スキャンでは、他の列とレコードの可視性スコープに対して追加のテーブル ルックアップが必要になるためです。

于 2013-01-15T20:42:21.690 に答える
0

見た目からすると、その call_id 列をコンポーネントごとに別々の列に分割する必要があります。たとえば、例で ID と IP アドレスのように見えるもののインデックスを含む追加の列を追加し、それらのインデックスを作成してから選択することができます。

于 2013-01-15T20:42:51.360 に答える