5

私は Oracle 10g を使用しており、2 つの大きなテーブル (数百万のレコード) を結合するビューがあります。次のように、ユーザーのデータの限られた「サンプル」を選択しようとしています。

select * from VIEW_NAME where ROWNUM < 5; 

これは非常に遅く、そうすべきではないと思います。結果の数行が必要なだけなので、Oracle は完全な結合を計算するべきではありません。

要件は、返される行の数をユーザーが対話的に指定できる必要があることです (結果の行が正確にどれであるかは問題ではありません)。これを達成する方法はありますか?(rownum または別のメソッドを使用)

(ビューの定義や最終的な SQL の作成方法を変更することはできますが、私の知る限り、必要な行数に関する情報をビューに動的に渡すことはできません)

編集: ビューの定義は非常に単純で、次のようになります。

CREATE OR REPLACE VIEW VIEW_NAME AS
(
    select
    e.id as ID,
    e.somefield as something,
    ... (some similar selects from e)
    c.field as anotherthing,
   ... (lots of other fields from c)
    from SCHEMA.TABLE1 e
    inner join SCHEMA.TABLE2 c on e.key = c.key
)

説明計画では、最初の数行を返すだけで時間がかからないため、驚くべきことではありませんが、両方のテーブルへの完全なテーブル アクセスについて言及しています。

EDIT2:これが完全な計画です

SQL> select * from table(dbms_xplan.display);

PLAN_TABLE_OUTPUT
------------------------------------------------------------------------------------------------------------------------------------------------------
Plan hash value: 2644394598

----------------------------------------------------------------------------------------------------------------------------------------------
| Id  | Operation                 | Name        | Rows  | Bytes |TempSpc| Cost (%CPU)| Time     | Pstart| Pstop |    TQ  |IN-OUT| PQ Distrib |
----------------------------------------------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT          |             |     4 |  1252 |       | 43546   (1)| 00:08:43 |       |       |        |      |            |
|*  1 |  COUNT STOPKEY            |             |       |       |       |            |          |       |       |        |      |            |
|   2 |   PX COORDINATOR          |             |       |       |       |            |          |       |       |        |      |            |
|   3 |    PX SEND QC (RANDOM)    | :TQ10002    |   696K|   207M|       | 43546   (1)| 00:08:43 |       |       |  Q1,02 | P->S | QC (RAND)  |
|*  4 |     COUNT STOPKEY         |             |       |       |       |            |          |       |       |  Q1,02 | PCWC |            |
|*  5 |      HASH JOIN BUFFERED   |             |   696K|   207M|    49M| 43546   (1)| 00:08:43 |       |       |  Q1,02 | PCWP |            |

PLAN_TABLE_OUTPUT
------------------------------------------------------------------------------------------------------------------------------------------------------
|   6 |       BUFFER SORT         |             |       |       |       |            |          |       |       |  Q1,02 | PCWC |            |
|   7 |        PX RECEIVE         |             |   696K|    90M|       |  5137   (1)| 00:01:02 |       |       |  Q1,02 | PCWP |            |
|   8 |         PX SEND HASH      | :TQ10000    |   696K|    90M|       |  5137   (1)| 00:01:02 |       |       |        | S->P | HASH       |
|   9 |          TABLE ACCESS FULL| TABLE1      |   696K|    90M|       |  5137   (1)| 00:01:02 |       |       |        |      |            |
|  10 |       PX RECEIVE          |             |   892K|   149M|       |  5260   (1)| 00:01:04 |       |       |  Q1,02 | PCWP |            |
|  11 |        PX SEND HASH       | :TQ10001    |   892K|   149M|       |  5260   (1)| 00:01:04 |       |       |  Q1,01 | P->P | HASH       |
|  12 |         PX BLOCK ITERATOR |             |   892K|   149M|       |  5260   (1)| 00:01:04 |     1 |   140 |  Q1,01 | PCWC |            |
|  13 |          TABLE ACCESS FULL| TABLE2      |   892K|   149M|       |  5260   (1)| 00:01:04 |     1 |   140 |  Q1,01 | PCWP |            |
----------------------------------------------------------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):

PLAN_TABLE_OUTPUT
------------------------------------------------------------------------------------------------------------------------------------------------------
---------------------------------------------------

   1 - filter(ROWNUM<5)
   4 - filter(ROWNUM<5)
   5 - access("E"."KEY"="C"."KEY")

27 rows selected.
4

4 に答える 4

3

/*+ NOPARALLEL */GuiGiの回答に従って、ヒントが何をするかを確認します。もう 1 つ試すことは、このために生成された計画を確認することです。

select /*+ FIRST_ROWS(10)*/ * from VIEW_NAME where ROWNUM < 5;
于 2012-09-21T04:56:32.940 に答える
1

NOPARALLEL ヒントをクエリに追加してみてください。

select /*+ NOPARALLEL */ * from VIEW_NAME where ROWNUM < 5; 

これは並列実行が選択された状況ですが、より多くの CPU と I/O を使用するため、パフォーマンスが低下する可能性があります。

于 2012-09-20T23:33:11.077 に答える
0

結合インデックスはありますか (オプティマイザによって選択されたアクセス パスは、インデックス付きのネストされたループである必要があります)。hash_join を (sort_merge_join と一緒に) 無効にしてみて、代替プレーンのコストを確認してください。通常のネストされたループが表示される場合、オプティマイザーは何らかの理由でインデックスを無視しました。

ビューを使用してクエリをチューニングする場合は、ビュー定義をインライン化してから、必要なアクセス パスをヒントにしてみてください。魔法のヒント (カーディナリティなど) を見つけた場合、それらをクエリ ブロックの外側に移動できる場合があります (これは特に、後のオラクル バージョンに当てはまります)。

于 2012-09-20T23:49:07.810 に答える
-1

次のことも試すことができます。

select * FROM 
(SELECT rownum ROW_NUMBER, YOUR_VIEW.* FROM  YOUR_VIEW) 
WHERE ROW_NUMBER> 2
于 2013-03-11T14:56:04.060 に答える