回答編集履歴

2 誤記の修正

Panzer_vor

Panzer_vor score 1632

2016/11/12 00:19  投稿

先ず始めにSQLを掲示できるレベルで掲示した方が、
回答者側も課題を共有しやすいので掲示できるならする方が良いでしょう。
ともあれ実行計画を見た感じだと、
無駄にサブクエリが使われている印象しかないので、
不要部分のカット、または別のアプローチを取れば速度改善は望めるでしょう。
後はSQLを段階的に分割して流すなどして、
時間がかかっている所を割り出すというやり方も有用です。
ちなみに同じようなサブクエリが何度も登場するなら、
最近のDBMSは軒並み**共通テーブル式(CTE)**をサポートしているので、
それへ置き換えることで速度改善を図るというのも一つの案でしょうね。
#実行計画の中身について
現在の質問者さんもレベルでは、
恐らく実行計画の単語の意味が分かったところで劇的に理解が深まることはない気がします。
Oracleに限らず、
いずれのDBMSも一般的な結合方法、インデックス項目の検索、非インデックス項目の検索には
大きな違いがないため、
この辺りの知識を深めるとどのDBMSを相手としてもある程度通用するスキルは身につくと思われます。
ただし一般論となりOracle特化の内容ではないので、興味がなければ読み飛ばしてください。
例えば結合方法だったら、
- NESTED LOOP(入れ子ループ)
- HASH JOIN(ハッシュ結合)
- SORT MERGE JOIN(マージ結合)
などがあります。
(※それぞれ特徴があるので調べてみてね。)
ただ結合方法は基本的にはDBMS側が最適なアルゴリズム選択をしてくれるので、
あまり気にする機会は少ないかなと思われます。
次にインデックス項目の検索方法ですが、これは大きく2種類となります。
- インデックス一意スキャン
- インデックス範囲スキャン
上記はインデックスが利用された検索となるので、
**大量にあるレコードから絞り込む**際には威力を発揮します。
他にもインデックスは**ソートされた状態で管理されるという特性**があるため、
GROUP BYやORDER BYなどソートが伴う処理ではインデックスを使わせて高速化という手法もあります。
ちなみにOracleの実行計画における、
**TABLE ACCESS  BY INDEX ROWID**というのは、
インデックス検索から物理レコードへのマッピングが行われている処理となります。
(要するにインデックスで検索済ませてから、物理レコードを取りにいっている)
最後に非インデックス項目の検索についてですが、
これは説明するまでもないですがインデックスを利用しないでは、
まず物理レコードを持ってきてからフィルタリングを行うことになります。
(OracleだとFilter(抽出条件)と表示されることが多い)
(OracleだとFilter(抽出条件)と表示されたはず)
この辺りは[こちら](http://use-the-index-luke.com/ja/sql/explain-plan/oracle/filter-predicates)が参考になります。
長くなりましたが、
この辺りの周辺知識を充実させているほど実行計画をより噛み砕けるので、
興味があったら勉強してみると良いかもしれませんね。
1 表現の修正

Panzer_vor

Panzer_vor score 1632

2016/11/12 00:18  投稿

先ず始めにSQLを掲示できるレベルで掲示した方が、
回答者側も課題を共有しやすいので掲示できるならする方が良いでしょう。
ともあれ実行計画を見た感じだと、
無駄にサブクエリが使われている印象しかないので、
不要部分のカット、または別のアプローチを取れば速度改善は望めるでしょう。
後はSQLを段階的に分割して流すなどして、
時間がかかっている所を割り出すというやり方も有用です。
ちなみに同じようなサブクエリが何度も登場するなら、
最近のDBMSは軒並み**共通テーブル式(CTE)**をサポートしているので、
それへ置き換えることで速度改善を図るというのも一つの案でしょうね。
#実行計画の中身について
現在の質問者さんもレベルでは、
恐らく実行計画の単語の意味が分かったところで劇的に理解が深まることはない気がします。
Oracleに限らず、
いずれのDBMSも一般的な結合方法、インデックスを利用した検索、インデックスを利用しない検索には
いずれのDBMSも一般的な結合方法、インデックス項目の検索、非インデックス項目の検索には
大きな違いがないため、
この辺りの知識を深めるとどのDBMSを相手としてもある程度通用するスキルは身につくと思われます。
ただし一般論となりOracle特化の内容ではないので、興味がなければ読み飛ばしてください。
例えば結合方法だったら、
- NESTED LOOP(入れ子ループ)
- HASH JOIN(ハッシュ結合)
- SORT MERGE JOIN(マージ結合)
などがあります。
(※それぞれ特徴があるので調べてみてね。)
ただ結合方法は基本的にはDBMS側が最適なアルゴリズム選択をしてくれるので、
あまり気にする機会は少ないかなと思われます。
次にインデックスを利用した検索方法ですが、これは大きく2種類となります。
次にインデックス項目の検索方法ですが、これは大きく2種類となります。
- インデックス一意スキャン
- インデックス範囲スキャン
上記はインデックスが利用された検索となるので、
**大量にあるレコードから絞り込む**際には威力を発揮します。
他にもインデックスは**ソートされた状態で管理されるという特性**があるため、
GROUP BYやORDER BYなどソートが伴う処理ではインデックスを使わせて高速化という手法もあります。
ちなみにOracleの実行計画における、
**TABLE ACCESS  BY INDEX ROWID**というのは、
インデックス検索から物理レコードへのマッピングが行われている処理となります。
(要するにインデックスで検索済ませてから、物理レコードを取りにいっている)
最後にインデックスが利用されない検索についてですが、
最後に非インデックス項目の検索についてですが、
これは説明するまでもないですがインデックスを利用しないでは、
まず物理レコードを持ってきてからフィルタリングを行うことになります。
(OracleだとFilter(抽出条件)と表示されることが多い)
この辺りは[こちら](http://use-the-index-luke.com/ja/sql/explain-plan/oracle/filter-predicates)が参考になります。
長くなりましたが、
この辺りの周辺知識を充実させているほど実行計画をより噛み砕けるので、
興味があったら勉強してみると良いかもしれませんね。

思考するエンジニアのためのQ&Aサイト「teratail」について詳しく知る