0
SELECT
/*+ INDEX(ID_BL_REF_NO REF_number_BL_idx*/ DECODE(BL_TYPE,'E',BL_ORIGIN_NAME,'I',BL_FINAL_NAME) FROM_PORT,
 DECODE(BL_TYPE,'I',BL_ORIGIN_NAME,'E',BL_FINAL_NAME) TO_PORT,
(BL_VESSEL_CONNECT||'/'||BL_VOYAGE_CONNECT||'/'||BL_PORT_CONNECT) Mother_vessel_voyage_port,
SUM(BLC_SIZE) No_of_20s,
SUM(BLC_SIZE)  No_of_40s,
SUM(DECODE(BLC_SIZE,'20',1,'40',2)) Teus,
SUM(BLC_GROSSWT) GrossWt,
round((BLC_GROSSWT/SUM(DECODE(BLC_SIZE,'20',1,'40',2))),2) AverageWt,
SUM(DECODE(BLF_MODE,'P',BLF_LOCAL_AMOUNT)) PREPAID,
SUM(DECODE(BLF_MODE,'C',BLF_LOCAL_AMOUNT)) COLLECT,
SUM(DECODE(BLF_MODE,'E',BLF_LOCAL_AMOUNT)) ELSEWHERE,
(SUM(DECODE(BLF_MODE,'P',BLF_LOCAL_AMOUNT)+DECODE(BLF_MODE,'C',BLF_LOCAL_AMOUNT)+DECODE(BLF_MODE,'E',BLF_LOCAL_AMOUNT))/SUM(DECODE(BLC_SIZE,'20',1,'40',2))) AVERAGE
FROM ID_BL_DETAILS,id_bl_containers,ID_BL_FREIGHT
WHERE BL_REFNO=BLC_REFNO
AND BLF_REFNO=BLC_REFNO
GROUP BY BL_VESSEL_CONNECT,BL_VOYAGE_CONNECT,BL_PORT_CONNECT,BL_ORIGIN_NAME,BL_LODPORT,BL_DISPORT,BL_FINAL_NAME,BLC_GROSSWT,BL_TYPE
4

3 に答える 3

5

WHERE 句には結合のみが含まれています。フィルターはありません。これは、クエリで少なくとも 1 つのテーブルのすべての行を考慮する必要があることを意味します。このことから、クエリは、インデックス付きの読み取りではなく、少なくとも 1 つのテーブルの FULL TABLE SCAN を実行する必要があるということになります。フル テーブル スキャンは、テーブル内のすべての行を取得する最も効率的な方法です。

したがって、INDEX ヒントの構文を修正しないでください。削除してください。

次に、クエリを実行するテーブルを決定します。これがビジネスロジックです。おそらくあなたの要件は次のようなものです

「BL_CONTAINERS のすべての行について、BL_DETAILS と BL_FREIGHT を要約します。」

その場合、BL_CONTAINERS の完全なテーブル スキャンが必要だと考えるかもしれません。しかし、BL_FREIGHT に BL_CONTAINERS よりも多くの行があり、すべての BLF_REF_NO が BL_REF_NO と一致する場合 (つまり、BL_FREIGHT.BLF_REF_NO に BL_CONTAINERS.BL_REF_NO を参照する外部キーがある場合)、BL_FREIGHT から駆動する方がよいでしょう。

これは、一致する BL_FREIGHT 行を持つ BL_CONTAINERS のみに関心がある場合に当てはまることに注意してください。しかし、使用されていないコンテナー (つまり、対応する BL_FREIGHT レコードがない) を含めたい場合は、外部結合を使用して BL_CONTAINERS テーブルから追い出す必要があります。

BL_DETAILS をミックスに投入すると、これらの考慮事項はさらに複雑になります。あなたのレポートは BL_DETAILS カテゴリに基づいているようです (Jeffrey が観察しているように、エイリアスや説明がなければクエリを理解するのは困難です)。したがって、おそらく BL_DETAILS がテーブルを駆動するための正しい候補です。

ご覧のとおり、チューニングには、ビジネス ロジックとデータ モデルの詳細への洞察が必要です。あなたはその地域の知識を持っていますが、私たちは持っていません。

役立つツールがあります。Oracle には、データベースがクエリを実行する方法を示す EXPLAIN PLAN があります。クエリ オプティマイザーはリリースごとに改善されているため、使用しているデータベースのバージョンは重要です。10g のドキュメントは次のとおりです。

注意すべき重要なことは、データベースが適切な計画を立てるために、データベースに正確な統計を与える必要があるということです。 詳細をご覧ください。

于 2011-03-11T08:03:50.017 に答える
2

クエリで実行explainし、適切なインデックスが設定されていることを確認してください。クエリの速度が向上します

http://www.sql.org/sql-database/postgresql/manual/sql-explain.html

于 2011-03-11T03:02:27.853 に答える
2

あなたの質問は、クエリに 9.968 秒かかり、0.5 秒以下にしたいと述べています。これは、これらの 9.968 秒がどこに費やされているかを知っている場合にのみ効果的に (可能であれば) 行うことができます。また、クエリのどこで時間が費やされているかを知るには、ステートメントを説明するだけでなく、そのクエリの実行をトレースする必要があります。後者は、クエリに費やされた時間の内訳を示します。

OTN には、その方法を説明するスレッドが 2 つあります。

最低限のことをしたい場合は、 http: //forums.oracle.com/forums/thread.jspa ?messageID=1812597 に従ってください。

詳細を知りたい場合は、 http: //forums.oracle.com/forums/thread.jspa ?threadID=863295 に従ってください。

ハッピートレース!

よろしく、
ロブ。

于 2011-03-11T09:54:12.397 に答える