2011-01-12 11 views
0

分割され索引付けされたかなり大きな表(450M行)を照会する必要があります。区分化された表の索引が使用されていません

は、このような構造とします...

  • load_num(int型)
  • のcust_id(int型)
  • ...いくつかのより多くの列

テーブルがload_numの上に分割されています、約3つの負荷が1つのパーティションに入ります。私はこのクエリを発行すると

(そうload_numは、パーティション内で一意ではありません)3つのインデックス、load_numを持っている彼ら二人がありますが、(そのためINT)最初の2列として

をCUST_ID:

select * 
from fact 
where load_num = 100 
     and cust_id = 12345 

リターンするにはかなり時間がかかりますので、私は計画を実行して正しいパーティションを取得しますが、その上でFULLテーブルスキャンを実行します。

2つの索引のいずれかを使用して、行を取得するためにパーティションでROWIDスキャンを実行できないのはなぜですか?

cust_idはかなり固有で、テーブルの統計情報は最新のものでなければなりません。私たちは10g Entrepriseに入っています。

MS SQLから来ていますので、私はまだOracleの方が高速です。事前に

おかげで、

ゲルト・ヤン

** EDIT:一部anonimized DDL:なぜオラクル行うために、2つの指標の一つを使用していない

CREATE TABLE FACT 
(
    LOAD_NUM NUMBER 
... columns .. 
, CUSTOMER_ID VARCHAR2(20 BYTE) 
.. columns 
) 
TABLESPACE "TS_A" 
PCTFREE 0 
INITRANS 1 
STORAGE 
( 
    BUFFER_POOL DEFAULT 
) 
PARALLEL 12 
PARTITION BY LIST (LOAD_NUM) 
(
    PARTITION FACT_46 VALUES (46) TABLESPACE FACT_PART_DATA_46 
    COMPRESS 
, PARTITION FACT_52 VALUES (52) TABLESPACE FACT_PART_DATA_52 
    COMPRESS 
, PARTITION FACT_56 VALUES (56) TABLESPACE FACT_PART_DATA_56 
    COMPRESS 
    ... more partitions ... 
)CREATE INDEX SOMESCHEMA.FACT_IDX2 ON SOMESCHEMA.FACT (LOAD_NUM ASC, CUSTOMER_ID ASC, OUTSTANDING_ID ASC) 
LOCAL 
(
    PARTITION FACT_DATA_46 
    LOGGING 
    TABLESPACE "FACT_DATA_46" 
    PCTFREE 10 
    INITRANS 2 
    STORAGE 
    ( 
    INITIAL 65536 
    MINEXTENTS 1 
    MAXEXTENTS 2147483645 
    BUFFER_POOL DEFAULT 
) 
    NOCOMPRESS 
, PARTITION FACT_DATA_52 
    LOGGING 
    TABLESPACE "FACT_DATA_52" 
    PCTFREE 10 
    INITRANS 2 
    STORAGE 
    ( 
    INITIAL 65536 
    MINEXTENTS 1 
    MAXEXTENTS 2147483645 
    BUFFER_POOL DEFAULT 
) 
    NOCOMPRESS 
, 
... etc etc .. 
) 
+2

はインデックス 'LOCAL'または'はGlobal'ていますか?正確な表と索引定義を(パーティション句を使用して)投稿してください。 – Quassnoi

+0

こんにちはQuassnoi、そこでDDLを編集しました。どうも! – gjvdkamp

答えて

3

パーティションをROWIDでスキャンして行を取得しますか?

Oracleがインデックスを使用していない理由を正確に伝えるのは難しいです。設定には、インデックスの使用を妨げるものがないためです。

ほとんどの場合、cust_idディストリビューションが偏っているため、OracleはPARTITION SCANをより効率的と見なします。

明示的にヒントを追加してみてくださいでした:

SELECT /*+ INDEX (f FACT_IDX2) */ 
     * 
FROM fact f 
WHERE load_num = 100 
     AND cust_id = 12345 

それは計画で使われていることを確認し、この方法は実際に高速であることを確認してください。

また、このクエリのリターンを何投稿してください。

SELECT COUNT(*), COUNT(DECODE(cust_id, 12345, 1)) 
FROM fact f 
WHERE load_num = 100 
+0

通常、インデックスのヒントを指定する必要がある場合、データが*非常に歪んでいるか、統計が正しくないことを意味します。あなたが最初のケースをカバーしているように見えますが、統計をチェックするのも便利です。 –

+0

@Adam:@opは統計情報が最新であると主張しています。 – Quassnoi

+0

Jst:SqlDevのdatailsタブに行くと、LAST_ANALYZED:03-DEC-10と表示されます。それ以来、負荷がかかっていないので、私は統計情報が最新であると仮定します。 (いずれの方法でも、cust_idの分布は変更されてはならない)。クエリのヒントを確認しています。 – gjvdkamp