0

私は Oracle 11g を使用しており、次の 3 つのコア テーブルがあります。

Customer - CUSTOMERID|DOB
CustomerName - CUSTOMERNAMEID|CustomerID|FNAME|LNAME
Address - ADDRESSID|CUSTOMERID|STREET|CITY|STATE|POSTALCODE

各テーブルに約 6,000 万行あり、データは米国とカナダの人口が混在しています。

Web サービスを呼び出すフロントエンド アプリケーションがあり、姓と部分的な郵便番号の検索を行います。したがって、私のクエリは基本的に

where CUSTOMERNAME.LNAME = ? and ADDRESS.POSTALCODE LIKE '?%'

通常、zip の最初の 3 桁が提供されます。

住所テーブルには、すべての通り/都市/州/郵便番号に関するインデックスと、州および郵便番号に関する別のインデックスがあります。

私はzip専用のインデックスを追加しようとしましたが、オラクルはクエリでそのインデックスを使用するように強制されましたが、違いはありませんでした。

約100行を返すには(一度に100行しか返さないページネーションがあります)、理想的ではない約30秒かかります。これを改善するにはどうすればよいですか?

4

1 に答える 1

0

問題は、適用しているフィルターがあまり選択的ではなく、異なるテーブルに適用されることです。これは、旧式の btree インデックスには適していません。コンテンツが非常に静的な場合は、ビットマップ インデックスを試すことができます。より正確には、姓の最初の 3 文字の関数ベースのビットマップ結合インデックスと、郵便番号列のビットマップ結合インデックスです。これは、姓が特定の文字で始まる非常に少数の人々が特定の郵便番号に住んでいることを前提としています。

CREATE BITMAP INDEX ix_customer_custname ON customer(SUBSTR(cn.lname,1,3))
FROM customer c, customername cn
WHERE c.customerid = cn.customerid;

CREATE BITMAP INDEX ix_customer_postalcode ON customer(SUBSTR(a.postalcode,1,3))
FROM customer c, address a
WHERE c.customerid = a.customerid;

成功すると、2 つのビットマップ インデックスが AND 接続されていることがわかります。実行時間は数秒に短縮されます。btree インデックスほど高速ではありません。

備考:

  • インデックスを 1 つまたは 2 つ作成する方が効率的かどうか、および関数が役立つかどうかについては、少し試してみる必要があるかもしれません。

  • 関数ベースで行う場合は、クエリの where 句にまったく同じ関数呼び出しを含める必要があります。そうしないと、インデックスは使用されません。

  • DML 操作はかなり遅くなります。これは、静的データを含むテーブルにのみ役立ちます。DML 操作は行全体の「範囲」をブロックすることに注意してください。同時 DML 操作では問題が発生します。

  • 応答時間は、BTREE インデックスのように瞬時ではなく、おそらく数秒です。

  • 私の知る限り、これはエンタープライズ版でのみ機能します。現在利用可能なエンタープライズ データベースがないため、構文はテストされていません。

  • それでも速度が不十分な場合は、customerid、姓、郵便番号、および btree インデックスを使用してマテリアライズド ビューを作成できます。しかし、それも高価です。

于 2017-10-17T22:00:23.340 に答える