Oracle で次の SQL ステートメントを実行しようとしていますが、実行に時間がかかります。
SELECT orderID FROM tasks WHERE orderID NOT IN
(SELECT DISTINCT orderID FROM tasks WHERE
engineer1 IS NOT NULL AND engineer2 IS NOT NULL)
IN 句にあるサブパートのみを実行すると、Oracle で非常に高速に実行されます。つまり、
SELECT DISTINCT orderID FROM tasks WHERE
engineer1 IS NOT NULL AND engineer2 IS NOT NULL
Oracle でステートメント全体が非常に長くかかるのはなぜですか? SQL Server では、ステートメント全体がすばやく実行されます。
または、使用する必要がある、より単純な/異なる/より優れたSQLステートメントはありますか?
問題に関する詳細:
- 各注文は多くのタスクで構成されています
- 各オーダーは割り当てられます (1 つまたは複数のタスクに Engineer1 と Engineer2 が設定されます)、またはオーダーは割り当て解除されます (すべてのタスクのエンジニア フィールドに null 値が設定されます)。
- 割り当てられていないすべての orderID を見つけようとしています。
違いが生じる場合に備えて、テーブルには最大 120,000 行あり、注文ごとに 3 つのタスクがあるため、最大 40,000 の異なる注文になります。
回答に対する回答:
- SQL Server と Oracle の両方で機能する SQL ステートメントを希望します。
- タスクには、orderID と taskID のインデックスしかありません。
- ステートメントの NOT EXISTS バージョンを試しましたが、キャンセルするまでに 3 分以上実行されました。おそらくステートメントの JOIN バージョンが必要ですか?
- orderID 列を持つ「orders」テーブルもあります。しかし、元の SQL ステートメントに含めないことで、質問を単純化しようとしていました。
元の SQL ステートメントでは、SQL ステートメントの最初の部分の各行に対して毎回サブクエリが実行されると思いますが、それは静的であり、一度だけ実行する必要がありますか?
実行中
ANALYZE TABLE tasks COMPUTE STATISTICS;
元の SQL ステートメントの実行速度が大幅に向上しました。
なぜ私はこれをしなければならないのか、またいつ/いつそれを実行する必要があるのか 、私はまだ興味がありますか?
統計は、さまざまな実行計画の効率を判断するために必要な Oracle のコストベースのオプティマイザ情報を提供します。たとえば、テーブル内の行数、行の平均幅、列ごとの最大値と最小値、列ごとの個別値の数、インデックスのクラスタリング係数など
小規模なデータベースでは、ジョブをセットアップして毎晩統計を収集し、そのままにしておくことができます。実際、これは 10g 未満のデフォルトです。大規模な実装では、通常、実行計画の安定性とデータの変更方法を比較検討する必要がありますが、これは難しいバランスです。
Oracle には、「動的サンプリング」と呼ばれる機能もあり、実行時にテーブルをサンプリングして関連する統計を決定するために使用されます。長時間実行されるクエリの潜在的なパフォーマンスの向上が、サンプリングのオーバーヘッドを上回るデータ ウェアハウスで使用されることがはるかに多くなります。