2
私は、異なる国のカレンダーに基づいて2つの日付間の営業日数を計算する関数(Oracle SQL)を作成しました。何千回も実行する必要があるため、速度は非常に重要です。 開始日、終了日、および指定されたカレンダーの名前(たとえば、 'US'、 'UK'など)を入力します。入力パラメータは異なるSQLで渡されますが、今はまだテスト中です。 この機能は休日テーブルを使用して、休日の間の休業日を検索します。この表には、各国の週末と祝祭日がすべて含まれています。問題は、カーソルを使用していても機能がかなり遅いことです。機能をより速くする方法について、どんなヒントもありますか?関数内の選択クエリが問題であると思われます。私は間違っているかもしれないが、それにも関わらず私は何をすべきか分からない。SQLの日付の最適化機能
CREATE OR REPLACE FUNCTION Test (in_dt1 DATE,
in_dt2 DATE,
in_Calender VARCHAR)
RETURN NUMBER
IS
Count_days NUMBER := 0;
beg_dt DATE;
End_dt DATE;
Curr_dt DATE;
Cursor_dato DATE;
CURSOR C1
IS
SELECT b.holiday
FROM calendars a
INNER JOIN holidays b ON a.calik = b.calik
WHERE a.cal = in_Calender AND holiday >= in_dt1 AND holiday <= in_dt2;
BEGIN
OPEN c1;
beg_dt := LEAST (in_dt1, in_dt2);
End_dt := GREATEST (in_dt1, in_dt2);
Curr_dt := beg_dt + 1;
<<OUTER>>
WHILE Curr_dt <= End_dt
LOOP
FETCH c1 INTO cursor_dato;
WHILE cursor_dato IS NULL
LOOP
Count_days := Count_days + 1;
Curr_dt := Curr_dt + 1;
EXIT OUTER WHEN Curr_dt = End_dt + 1;
END LOOP;
WHILE Curr_dt < cursor_dato
LOOP
Count_days := Count_days + 1;
Curr_dt := Curr_dt + 1;
EXIT OUTER WHEN Curr_dt = End_dt;
END LOOP;
IF Curr_dt > cursor_dato
THEN
Count_days := Count_days + 1;
END IF;
Curr_dt := Curr_dt + 1;
END LOOP;
CLOSE c1;
RETURN Count_days;
END;
なぜ、デュアルから選択するのですか? 'count_days:= trunc(beg_dt) - trunc(end_dt);'?特にパフォーマンスが考慮されている場合は、無意味なコンテキスト切り替えを避けることをお勧めします。また、なぜ 'count(1)'? ['count(*)'は高速です!](https://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:1156151916789#25335122556076)* {;-) – Boneist
@Boneistあなたは絶対に正しいです。 SQLとして投稿したコピーされたコード – Kacper
@Boneist私は、最近のバージョンのoracleではcount(*)とcount(1)の論争が解明されていると信じています。少なくとも11g以上。 – Sentinel