パーティション・プルーニングから最大限のパフォーマンスを得るには、データベースによって変換が必要となるデータ型を指定しないようにしてください。データ型が変換されると、その他の点で静的プルーニングが可能な場合でも、通常は動的プルーニングが行われます。静的プルーニングを利用するSQL文は、動的プルーニングを利用するSQL文よりもパフォーマンスが高くなります。
OracleのDATE
データ型を使用すると、一般的なデータ型変換が行われます。OracleのDATE
データ型は文字列ではありませんが、データベースを問い合せたときに文字列のように表示されます。表示形式はインスタンスまたはセッションのNLS設定で定義されます。したがって、データをDATE
フィールドに挿入するとき、またはそのようなフィールドに述語を指定するとき、同じ変換を逆向きに実行する必要があります。
変換は暗黙に実行するか、TO_DATE
変換を指定して明示的に実行することができます。TO_DATE
関数を適切に適用した場合のみ、データベースが一意に日付値を判別して、その値を静的プルーニングに潜在的に使用できるようになります。これは、1つのパーティションにアクセスするために特に役立ちます。
Oracle DatabaseのサンプルSH
スキーマに対して実行する次の例を考えてください。2000年の合計収益を問い合せる場合があります。この問合せの結果を取得する方法はたくさんありますが、すべての方法の効率が同じではありません。
explain plan for SELECT SUM(amount_sold) total_revenue FROM sales, WHERE time_id between '01-JAN-00' and '31-DEC-00';
計画は次のようになります。
---------------------------------------------------------------------------------------------------- | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | Pstart| Pstop | ---------------------------------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | 1 | 13 | 525 (8)| 00:00:07 | | | | 1 | SORT AGGREGATE | | 1 | 13 | | | | | |* 2 | FILTER | | | | | | | | | 3 | PARTITION RANGE ITERATOR| | 230K| 2932K| 525 (8)| 00:00:07 | KEY | KEY | |* 4 | TABLE ACCESS FULL | SALES | 230K| 2932K| 525 (8)| 00:00:07 | KEY | KEY | ---------------------------------------------------------------------------------------------------- Predicate Information (identified by operation id): --------------------------------------------------- 2 - filter(TO_DATE('01-JAN-00')<=TO_DATE('31-DEC-00')) 4 - filter("TIME_ID">='01-JAN-00' AND "TIME_ID"<='31-DEC-00')
この場合、PSTART
とPSTOP
両方のキーワードKEY
は、動的パーティション・プルーニングが実行時に行われることを示します。次の例について考えてください。
explain plan for select sum(amount_sold) from sales where time_id between '01-JAN-2000' and '31-DEC-2000' ;
この実行計画は次のようになります。
---------------------------------------------------------------------------------------- | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Pstart| Pstop | ---------------------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | 1 | 13 | 127 (4)| | | | 1 | SORT AGGREGATE | | 1 | 13 | | | | | 2 | PARTITION RANGE ITERATOR| | 230K| 2932K| 127 (4)| 13 | 16 | |* 3 | TABLE ACCESS FULL | SALES | 230K| 2932K| 127 (4)| 13 | 16 | ---------------------------------------------------------------------------------------- Predicate Information (identified by operation id): --------------------------------------------------- 3 - filter("TIME_ID"<=TO_DATE(' 2000-12-31 00:00:00', "syyyy-mm-dd hh24:mi:ss'))
注意:
Time
列は、この実行計画からは削除されています。
この実行計画では静的パーティション・プルーニングが示されます。問合せは、隣接するパーティション13から16にアクセスします。この場合は、日付形式の指定方法が、NLS日付形式の設定と一致しています。この例では最も効果的な実行計画が示されていますが、NLS日付形式設定を利用して特定の形式を定義することはできません。
alter session set nls_date_format='fmdd Month yyyy'; explain plan for select sum(amount_sold) from sales where time_id between '01-JAN-2000' and '31-DEC-2000' ;
この実行計画は次のようになります。
----------------------------------------------------------------------------------------- | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Pstart| Pstop | ----------------------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | 1 | 13 | 525 (8)| | | | 1 | SORT AGGREGATE | | 1 | 13 | | | | |* 2 | FILTER | | | | | | | | 3 | PARTITION RANGE ITERATOR| | 230K| 2932K| 525 (8)| KEY | KEY | |* 4 | TABLE ACCESS FULL | SALES | 230K| 2932K| 525 (8)| KEY | KEY | ----------------------------------------------------------------------------------------- Predicate Information (identified by operation id): --------------------------------------------------- 2 - filter(TO_DATE('01-JAN-2000')<=TO_DATE('31-DEC-2000')) 4 - filter("TIME_ID">='01-JAN-2000' AND "TIME_ID"<='31-DEC-2000')
注意:
Time
列は、この実行計画からは削除されています。
動的プルーニングを使用するこの計画は、静的プルーニングの実行計画よりも効率が悪くなります。静的パーティション・プルーニング計画を保証するには、パーティション列のデータ型と一致するようにデータ型を明示的に変換する必要があります。次に例を示します。
explain plan for select sum(amount_sold) from sales where time_id between to_date('01-JAN-2000','dd-MON-yyyy') and to_date('31-DEC-2000','dd-MON-yyyy') ; ---------------------------------------------------------------------------------------- | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Pstart| Pstop | ---------------------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | 1 | 13 | 127 (4)| | | | 1 | SORT AGGREGATE | | 1 | 13 | | | | | 2 | PARTITION RANGE ITERATOR| | 230K| 2932K| 127 (4)| 13 | 16 | |* 3 | TABLE ACCESS FULL | SALES | 230K| 2932K| 127 (4)| 13 | 16 | ---------------------------------------------------------------------------------------- Predicate Information (identified by operation id): --------------------------------------------------- 3 - filter("TIME_ID"<=TO_DATE(' 2000-12-31 00:00:00', 'syyyy-mm-dd hh24:mi:ss'))
注意:
Time
列は、この実行計画からは削除されています。
関連項目:
DATE
データ型の詳細は、『Oracle Database SQL言語リファレンス』を参照してください。
NLSの設定およびグローバリゼーションの問題の詳細は、『Oracle Databaseグローバリゼーション・サポート・ガイド』を参照してください。