1

Oracle データベースにタイムスタンプ列 nextTime と文字列列 destName を持つテーブルがあります。他にも列がありますが、この場合に関連するのはこれらの 2 つだけです。特定の間隔内に nextTime を持つ個別の destName を返すクエリを設計しようとしています。返される行数は最大 1000 です。間隔内に1000を超える異なるdestNameがある場合、クエリで1000行を返す必要があります。

私は実際に機能しているクエリを持っていますが、遅すぎます:

select destName 
from (select /*+ index(tblDestNames tbldestnames_destname)*/ distinct destName
from (select /*+ index(tblDestNames tbldestnames_nextTime)*/ destName
from tblDestNames 
where nextTime < :1 and nextTime >= :2 and destName is not null)) 
where rownum <= 1000; 

よりスマートなクエリを設計する方法、またはこの既存のクエリを最適化する方法についてのアイデアは非常に高く評価されます。

4

2 に答える 2

7

クエリをこれに単純化しない理由があるかどうかはわかりません。

select destName 
from (
    select distinct destName
    from tblDestNames 
    where nextTime < :1 and nextTime >= :2 and destName is not null
    )
where rownum <= 1000; 

ただし、これはパフォーマンスの問題を解決しません。問題はこれです:

where rownum <= 1000

rownum を「rank」と「over」に置き換えると、次のようになります。

select distinct destName
from (
    select
       destName
    from
       (select destName, rank()
        over (order by destName desc ) rnk
        from tblDestNames
        where nextTime < :1 and nextTime >= :2 and destName is not null) 
    where rnk <= 1000;
    )

おまけに、「over」を使用して、表示する結果と表示しない結果の順序を選択できます。

編集:実際には、次のようにさらに単純化できます。

select
   distinct destName
from
   (select destName, rank()
    over (order by destName desc ) rnk
    from tblDestNames
    where nextTime < :1 and nextTime >= :2 and destName is not null) 
where rnk <= 1000;
于 2011-08-10T08:50:14.243 に答える
1

拾ってきたもの

  1. 本当によくわからない限り、実行計画の最適化はRDBMSに任せるべきです
  2. 最も内側のサブクエリから重複した名前を返す必要はありません

セマンティクスがわずかに異なる単純なクエリ:

SELECT destName
FROM (SELECT DISTINCT destName
      FROM tblDestNames
      WHERE destName IS NOT NULL 
        AND nextTime NOT BETWEEN :1 and :2)
WHERE rownum <= 1000;

BETWEEN包括的、つまりx BETWEEN y AND zequalsであることに注意してくださいy <= x <= z。上限を除外するには、あなたが行った方法でそれを行うか、nextTime の単位のいずれかでパラメーター :2 を減らす必要があります。

于 2011-08-10T08:49:13.020 に答える