1

私はdjangoを使用していますが、すべてのクエリはdjangoによって作成されているため、手書きのクエリはありません...

のテーブルがBillRecordsあり、フィールドがありますsubscriberno。私のdjangoフィルターでは、次のようなフィルタークエリを使用します。

BillRecords.objects.filter(subscriberno__icontains='123456')

subscriberno顧客が実数のかなり短縮されたバージョンであるかもしれないと言ったので...

そのフィルターは次のようなクエリを出力します。

SELECT "subscriberno" FROM "BillRecords" WHERE UPPER("subscriberno"::text) LIKE UPPER(E'%123456%');

subscriberno一部の数値にはアルファと一部の特殊文字が含まれているため、は文字フィールドです。

私のデータベースには、同僚によって作成された、その列の2つのインデックスがあります。

"BillRecords_subscriberno" btree (subscriberno)
"BillRecords_fsubscriberno_like" btree (subscriberno varchar_pattern_ops)

このようなクエリに2つのインデックスを使用するのは論理的だと思います。私たちのすべてのdjangoフィルターはicontains、上記のようなクエリを作成するために使用します。

クエリのPostgres分析は次のとおりです。

Seq Scan on BillRecords  (cost=0.00..159782.40 rows=370 width=15) (actual time=579.637..3705.079 rows=10 loops=1)
Filter: (upper((subscriberno)::text) ~~ '%123456%'::text)
Total runtime: 3705.106 ms
(3 rows)

したがって、私が見る限り、インデックスは使用されていません。インデックスusegaはデータの挿入と更新にコストがかかるため、(この分析からわかる限り)使用されていない2つのインデックスを持つことは論理的ではないように思われました。

djangoが同様のicontanisフィルターに対して異なるクエリを出力する可能性はありますか?または、私のインデックスはまったく役に立たないのですか?

4

3 に答える 3

1

アンカーされていないlikeステートメントでインデックスを使用することはできません。

upper(foo) like 'bar%' -- index on upper(foo)
upper(foo) like '%bar' -- no index
reverse(upper(foo)) like 'rab%' -- index on reverse(upper(foo))
upper(foo) like '%bar%' -- no index

ただし、検索ウィンドウを縮小したい場合は、トリグラムの使用が役立つ場合があります。

于 2011-07-26T10:18:48.440 に答える
1

含む (部分文字列) クエリは、インデックスにアクセスできません (演算子がフルテキスト モジュールにリンクされている場合を除く)。一方、start-with クエリはインデックスの恩恵を受けることができます。カーディナリティが低すぎず、挿入が通常大きなバッチではなく OLTP シナリオで行われる場合、インデックス作成のオーバーヘッドは無視できます。

統計を正しく読み取れますか? 370 行をスキャンするのに約 4 秒かかりますか?

PS別のアプローチを検討することもできます: 関数ベースのインデックスを使用して、おそらくsubscribernoの最後の4文字を、たとえばsubscribernameの最初の3文字に連結し、検索でLIKEの代わりにstarts-withまたはequalsを使用します-ワイルドカードで予約された用語。

于 2011-07-26T10:13:35.613 に答える
1

インデックスがまったく使用されているかどうかを確認する簡単な方法は、次を確認することです

SELECT * FROM pg_stat_user_indexes;

すべてのクエリが表示されているようなものである場合、パターンが固定されていないため、それらは確実に使用されません。これに対処したい場合は、全文検索やトライグラムなどを使用して、検索を少し再設計する必要があります。

于 2011-07-26T21:37:13.327 に答える