6

以下の内部クエリの OVER 部分にある「ORDER BY lro_pid」句の影響を軽減する方法はありますか?

SELECT *
  FROM (SELECT a.*, 
               Row_Number() over (PARTITION BY search_point_type 
                                      ORDER BY lro_pid) spt_rank
          FROM lro_search_point a
      ORDER BY spt_rank)
 WHERE spt_rank = 1;

完全に別の変数で並べ替えたいので、パーティション内でこの結果を並べ替える必要はありません。lro_pid はインデックス付きの列ですが、現状ではリソースの無駄遣いのように見えます。(おそらく、順序付けを単一の行の範囲に制限する方法がありますか??パーティション内のソートに時間/エネルギーがまったく費やされないことを願っています)

4

3 に答える 3

6

試してみるいくつかのこと:

たとえばORDER BY 'constant'、OVER句でできますか?

定数による順序付けが許可されていない場合はどうORDER BY (lro_pid * 0)ですか?

私は Oracle の専門家ではありません (MSSQL の方が得意です)。したがって、質問に答えてください。

于 2011-06-02T22:28:54.753 に答える
5

@Will Aが提案したように、分析ORDER BYで定数を使用するのが最速の方法のようです。オプティマイザーは引き続き並べ替えを実行しますが、列を並べ替えるよりも高速です。また、おそらく 2 番目の ORDER BY を削除するか、少なくとも外側のクエリに移動する必要があります。

以下は私のテストケースです:

--Create table, index, and dummy data.
create table lro_search_point(search_point_type number, lro_pid number, column1 number
    ,column2 number, column3 number);
create index lro_search_point_idx on lro_search_point(lro_pid);
insert /*+ append */ into lro_search_point
select mod(level, 10), level, level, level, level from dual connect by level <= 100000;
commit;


--Original version.  Averages 0.53 seconds.
SELECT * FROM 
(
    SELECT a.*, Row_Number() over (PARTITION BY search_point_type ORDER BY lro_pid) spt_rank
    FROM lro_search_point a
    ORDER BY spt_rank
)
WHERE spt_rank=1;


--Sort by constant.  Averages 0.33 seconds.
--This query and the one above have the same explain plan, basically it's
--SELECT/VIEW/SORT ORDER BY/WINDOW SORT PUSHED RANK/TABLE ACCESS FULL.
SELECT * FROM 
(
    SELECT a.*, Row_Number() over (PARTITION BY search_point_type ORDER BY -1) spt_rank
    FROM lro_search_point a
    ORDER BY spt_rank
)
WHERE spt_rank=1;


--Remove the ORDER BY (or at least move it to the outer query).  Averages 0.27 seconds.
SELECT * FROM 
(
    SELECT a.*, Row_Number() over (PARTITION BY search_point_type ORDER BY -1) spt_rank
    FROM lro_search_point a
)
WHERE spt_rank=1;


--Replace analytic with aggregate functions, averages 0.28 seconds.
--This idea is the whole reason I did this, but turns out it's no faster.  *sigh*
--Plan is SELECT/SORT GROUP BY/TABLE ACCESS FULL.
--Note I'm using KEEP instead of just regular MIN.
--I assume that you want the values from the same row.
SELECT a.search_point_type
    ,min(lro_pid) keep (dense_rank first order by -1)
    ,min(column1) keep (dense_rank first order by -1)
    ,min(column2) keep (dense_rank first order by -1)
    ,min(column3) keep (dense_rank first order by -1)
FROM lro_search_point a
group by a.search_point_type;
于 2011-06-03T05:59:37.480 に答える
-1

句を省略するには、rownumORDER BYを使用できますORDER BY

于 2012-02-07T06:39:59.377 に答える