0

私はSQLのショートカットに精通していないので、ここでの頭脳を活用して、使用しているクエリを高速化することを望んでいました。現在、Oracle8iを使用しています。

質問があります:

SELECT 
    NAME_CODE, ACTIVITY_CODE, GPS_CODE 
FROM
    (SELECT 
         a.NAME_CODE, b.ACTIVITY_CODE, a.GPS_CODE, 
         ROW_NUMBER() OVER (PARTITION BY a.GPS_DATE ORDER BY b.ACTIVITY_DATE DESC) AS RN
     FROM GPS_TABLE a, ACTIVITY_TABLE b
     WHERE a.NAME_CODE = b.NAME_CODE
       AND a.GPS_DATE >= b.ACTIVITY_DATE 
       AND TRUNC(a.GPS_DATE) > TRUNC(SYSDATE) - 2)
WHERE 
    RN = 1

これには約7分かかり、実行には10秒かかります。

現在、GPS_TABLEは6.586.429行であり、新しいGPS座標がシステムに追加されるにつれて増加し続け、毎日6列で約8.000行増加します。

現在ACTIVITY_TABLEは1.989.093行であり、新しいアクティビティがシステムに追加されるにつれて増加し続け、毎日31列で約2.000行増加します。

したがって、これらはすべて小さなテーブルではなく、このクエリまたは同様のクエリを実行すると常にタイムヒットが発生することを理解しています。ご覧のとおり、私はすでに過去2日間分のデータに制限していますが、それを高速化するために何かをいただければ幸いです。

4

2 に答える 2

3

最強のフィルターは、の最後の2日間のフィルターのようですGPS_TABLEGPS_TABLEを約15,000行にフィルタリングする必要があります。したがって、改善の最良の候補の1つは、列のインデックスGPS_DATEです。

TRUNC(a.GPS_DATE) > TRUNC(SYSDATE) - 2フィルタはと同等であることがわかりますa.GPS_DATE > TRUNC(SYSDATE) - 2。したがって、クエリを変更すると、列の単純なインデックスが機能します。変更できない場合は、に関数ベースのインデックスを追加できますTRUNC(GPS_DATE)

このインデックスを設定したら、の行にアクセスする必要がありますACTIVITY_TABLE。あなたの参加の問題は、私たちがすべての古い活動を取得し、したがってテーブルのかなりの部分を取得することです。これは、そのままの結合はインデックススキャンでは効率的ではないことを意味します。

ACTIVITY_TABLE(name_code, activity_date DESC)特にこのインデックスを使用して、最小限の作業で最後のアクティビティを取得するインデックスとPL/SQL関数を定義することをお勧めします。

CREATE OR REPLACE FUNCTION get_last_activity (p_name_code VARCHAR2, 
                                              p_gps_date DATE) 
RETURN ACTIVITY_TABLE.activity_code%type IS
   l_result ACTIVITY_TABLE.activity_code%type;
BEGIN
   SELECT activity_code
     INTO l_result
     FROM (SELECT activity_code
             FROM activity_table
            WHERE name_code = p_name_code
              AND activity_date <= p_gps_date
            ORDER BY activity_date DESC)
     WHERE ROWNUM = 1;
   RETURN l_result;
END;

この関数を使用するようにクエリを変更します。

SELECT a.NAME_CODE,
       a.GPS_CODE,
       get_last_activity(a.name_code, a.gps_date)
  FROM GPS_TABLE a
 WHERE trunc(a.GPS_DATE) > trunc(sysdate) - 2
于 2012-09-04T11:37:36.380 に答える
1

SQLクエリの最適化は、通常、次の方法で実行されます。

  1. いくつかのインデックスを追加します
  2. 同じ情報を取得するために別の方法を試してください

したがって、のインデックスを追加することから始めACTIVITY_DATEます。おそらく、条件で使用される他のいくつかのフィールドを追加します。

于 2012-09-04T11:36:57.190 に答える