2

H 私は、似ているがわずかに異なる 2 つの SQL クエリの実行にかかる時間に大きな違いがある理由を理解しようとしています。以下の 2 つのサンプルと報告された時間に基づいて、ご意見をいただければ幸いです。

最初のクエリは次のとおりで、実行には約 115 ~ 154 秒かかります。

SELECT * FROM 
(
    SELECT a.*, ROWNUM rnum 
    FROM 
    (
        SELECT ERR_ID, ERR_CREATED_BY,TO_CHAR(ERR_CREATED_DATE, 'DD/MM/YYYY H24:MI'),  
               ERR_SOURCE, ERR_DETAIL  
        FROM tdsys_errors  err   
        WHERE ERR_SOURCE = 'Online Transaction'  
        ORDER BY ERR_ID DESC 
    ) a 
    WHERE ROWNUM <= 25
) 
WHERE rnum > 0;

2 番目のクエリは、「ORDER BY ERR_ID DESC」部分の位置に関してわずかな変更があり、実行に約 0.07 秒かかります。

SELECT * FROM 
(
    SELECT a.*, ROWNUM rnum 
    FROM 
    (
        SELECT ERR_ID, ERR_CREATED_BY,TO_CHAR(ERR_CREATED_DATE, 'DD/MM/YYYY H24:MI'),  
               ERR_SOURCE, ERR_DETAIL  
        FROM tdsys_errors  err   
        WHERE ERR_SOURCE = 'Online Transaction'    
    ) a 
    WHERE ROWNUM <= 25
) 
WHERE rnum > 0
ORDER BY ERR_ID DESC;

結果が到着した後に2番目のクエリが注文され、最初のクエリが一度に実行しようとしていると思います。これは SQL のベスト プラクティス ケースですか?

ありがとう

4

4 に答える 4

6

あなた自身の要約は正しいです。最初のクエリは tdsys_errors からの行を err_id で並べ替え、それらの最初の 25 を取り、それらを返します。2 番目のクエリは 25 行 (順序は保証されません) を出力し、それらのランダムな 25 行を並べ替えます。

于 2012-04-19T15:27:24.030 に答える
5

最初のケースでは、最初の25行を選択していますerr_id。クエリからすべての結果を見つけてから、どの 25 を使用するかを判断する前にすべての結果を並べ替える必要があり、これには明らかに時間がかかります。

2 番目のケースでは、順序付けされていないクエリによって返された最初の 25 行を取得します。

2 つのクエリから異なる結果が得られる可能性があります。たまたま同じ結果が得られたとしても、常に同じ結果になると想定すべきではありません。

于 2012-04-19T15:26:57.087 に答える
2

その理由は、最初のクエリではtdsys_errorsテーブル内のすべての行を並べ替える必要があるのに対し、2 番目のクエリでは、内側のクエリから返された 25 行のみを並べ替える必要があるためです。

2 つのクエリの出力は異なる場合があることに注意してください。

于 2012-04-19T15:26:35.277 に答える
1

Oracle 9i 以降を使用していると仮定すると、ウィンドウ/分析関数を使用できるため、ROW_NUMBER()複数のサブクエリを使用する必要はありません。

SELECT * FROM (
    SELECT ERR_ID, ERR_CREATED_BY, TO_CHAR(ERR_CREATED_DATE, 'DD/MM/YYYY H24:MI')
         , ERR_SOURCE, ERR_DETAIL, ROW_NUMBER() OVER (ORDER BY ERR_ID DESC) AS rnum
       FROM tdsys_errors  err   
      WHERE ERR_SOURCE = 'Online Transaction'
) WHERE rnum <= 25
 ORDER BY ERR_ID DESC;

お役に立てれば。

于 2012-04-19T17:39:07.760 に答える