0
select * from (
 select t_tmp_a.*, rownum t_tmp_id from (
 select  t.*, i.counts  
 from table1 t, (select id, count(id) counts from table2 group by id) i
 where t.id=i.id and t.kindid in (0,1,3) order by t.id desc
) t_tmp_a where rownum <= 20) t_tmp_b where t_tmp_id >= 11;

table1 と table2 には、テーブルごとに 200 万を超えるデータがあります。このクエリを実行するには 18 秒が必要です。このクエリを実行する前に、合計カウントを計算する必要があるため、約 7 秒かかるため、25 秒以上かかります。最適化するアイデアはありますか?

4

1 に答える 1

1

ページ付けは通常、結果を人間に表示するためのメカニズムです。200万行のデータを読みたがる人間はいません。

したがって、このクエリが実際に実際の人に行を提示している場合、対処する必要があるのは、結果全体のサイズを人間サイズのサイズに縮小することです。したがって、データベースに追加のフィルターを適用して、フォーカスされた結果セットを返す必要があります。ユーザーに感謝するだけでなく、ネットワーク管理者にも感謝します。

一方、このデータの大洪水の対象となる受信者がコンピューターまたはその他の機械的デバイスである場合は、すべてを提供するだけです。マシンはほとんどページを気にしません。または、そうする場合(スプレッドシート、プリンターなど)、ページ付けを処理するための組み込みのサブルーチンがあります。


そのため、元のクエリの実行に時間がかかるという問題が残ります。説明プランまたは統計(table1検索条件に適合する行数?これらの値の制限はkindid?)がなければ、これを解決することは困難です。

「kindidはchoose(0,1,3)が3つしかないタイプです」

Fnord。KINDIDが3つの選択肢しか持てない場合、WHERE句でKINDIDを使用する意味は何ですか?

実際、WHERE句から削除すると、クエリのパフォーマンスが大幅に向上する可能性があります。その列のヒストグラムを収集していない限り、Oracleはそれin (0,1,3)が何らかの形で結果セットを制限すると想定します。一方、これは、行の大部分がその列にNULLを持っている場合にのみ当てはまります。その場合は、を使用することをお勧めしますkindid is not null

于 2012-10-14T11:35:33.593 に答える