提高CURSOR for LOOP的效率

时间:2014-04-18 06:27:17

标签: sql plsql oracle11g

我有两个CURSOR FOR LOOPS,一个在公共假期找AVG(USAGE),另一个在平日找到AVG(USAGE)。从这些中检索的信息被写入另一个表中。它的运行速度相当缓慢,我确信必须有一种提高效率的方法,但我仍然很擅长这一点,我怀疑我的代码充其量只是笨重。

create or replace PROCEDURE USAGE_FORECAST AS
  v_dayNumber NUMBER;  
  v_halfHour NUMBER;

  CURSOR c_nonPublicHoliday is
    SELECT STREET, SUBURB, DAY, HH, AVG(USAGE) AVG_USAGE
      FROM INITIAL_TABLE, HOLIDAY_TABLE
      WHERE (to_char(day, 'd') = v_dayNumber
             OR to_char(day, 'd') = v_dayNumber-7)
            AND INITIAL_TABLE.DAY IN (SELECT HOLIDAY_DATE FROM HOLIDAY_TABLE)
            AND HH = v_halfHour
      GROUP BY STREET, SUBURB, DAY, HH;

  CURSOR c_publicHoliday is
    SELECT STREET, SUBURB, DAY, HH, AVG(USAGE) AVG_USAGE
      FROM INITIAL_TABLE, HOLIDAY_TABLE
      WHERE V_NEM_RM16.DAY IN (SELECT HOLIDAY_DATE FROM HOLIDAY_TABLE)
            AND HH = v_halfHour
      GROUP BY STREET, SUBURB, DAY, HH;                             

BEGIN
  FOR v_forecastDay IN 1..7 LOOP
    v_dayNumber := v_forecastDay;

    FOR v_halfHourInterval IN 1..48 LOOP
      v_halfHour := v_halfHourInterval;

      FOR R1 IN c_nonPublicHoliday LOOP
        INSERT INTO LOCAL_TABLE
          (STREET,    SUBURB,    DAY,     HH,    USAGE)
        VALUES
          (R1.STREET, R1.SUBURB, SYSDATE, R1.HH, R1.AVG_USAGE);
      END LOOP;

      FOR R1 IN c_PublicHoliday LOOP
        INSERT INTO LOCAL_TABLE
          (STREET,    SUBURB,    DAY,  HH,       USAGE)
        VALUES
          (R1.STREET, R1.SUBURB, SYSDATE, R1.HH, R1.AVG_USAGE);
      END LOOP;
    END LOOP;
  END LOOP;

现在,它正在运行CURSOR FOR循环,无论这一天是否是公众假期。我确信有一种方法可以构建我的select语句,这样就没有必要了,但是现在它超出了我的范围。其次,我怀疑公共假期回复了太多信息,但这可能只是因为下周在澳大利亚有很多公众假期。

1 个答案:

答案 0 :(得分:0)

我修改了你的查询,但是你必须检查它。

create or replace PROCEDURE USAGE_FORECAST AS
  v_dayNumber NUMBER;  
  v_halfHour NUMBER;

  CURSOR c_nonPublicHoliday is
    SELECT STREET, SUBURB, DAY, HH, AVG(USAGE) AVG_USAGE
      FROM INITIAL_TABLE, HOLIDAY_TABLE
      WHERE (to_char(day, 'd') = v_dayNumber
             OR to_char(day, 'd') = v_dayNumber-7)
            /*AND INITIAL_TABLE.DAY IN (SELECT HOLIDAY_DATE FROM HOLIDAY_TABLE)*/
            AND exists (SELECT 1 FROM HOLIDAY_TABLE h where h.HOLIDAY_DATE  = INITIAL_TABLE.DAY )
            AND HH = v_halfHour
      GROUP BY STREET, SUBURB, DAY, HH;

  CURSOR c_publicHoliday is
    SELECT STREET, SUBURB, DAY, HH, AVG(USAGE) AVG_USAGE
      FROM INITIAL_TABLE, HOLIDAY_TABLE
      WHERE /*V_NEM_RM16.DAY IN (SELECT HOLIDAY_DATE FROM HOLIDAY_TABLE)*/
            exists (SELECT 1  FROM HOLIDAY_TABLE H where H.HOLIDAY_DATE = V_NEM_RM16.DAY)
            AND HH = v_halfHour
      GROUP BY STREET, SUBURB, DAY, HH;                             

BEGIN
  FOR v_forecastDay IN 1..7 LOOP
    v_dayNumber := v_forecastDay;

    FOR v_halfHourInterval IN 1..48 LOOP
      v_halfHour := v_halfHourInterval;

      FOR R1 IN c_nonPublicHoliday LOOP
        INSERT INTO LOCAL_TABLE
          (STREET,    SUBURB,    DAY,     HH,    USAGE)
        VALUES
          (R1.STREET, R1.SUBURB, SYSDATE, R1.HH, R1.AVG_USAGE);
      END LOOP;

      FOR R1 IN c_PublicHoliday LOOP
        INSERT INTO LOCAL_TABLE
          (STREET,    SUBURB,    DAY,  HH,       USAGE)
        VALUES
          (R1.STREET, R1.SUBURB, SYSDATE, R1.HH, R1.AVG_USAGE);
      END LOOP;
    END LOOP;
  END LOOP;