为MySQL修改Oracle过程

aamkag61  于 2023-11-17  发布在  Oracle
关注(0)|答案(1)|浏览(169)

我真的很难将Oracle过程修改为MySQL,因为在MySQL中使用游标将运行时间从2分钟增加到6小时!!
这是我的Oracle主过程,它调用其他过程,但我相信它可能需要一个完整的重组工作的MySQL:

create or replace PROCEDURE lpUsers_master AS
    v_SEASON_NUMBER_DERIVED NUMBER;
    v_LEAGUE_COUNTRY VARCHAR2(100);
    v_LEAGUE_LEVEL NUMBER;
    v_ALPHA2CODE_DERIVED VARCHAR2(2);
    v_count NUMBER;
    v_count_plus NUMBER;
BEGIN
    -- Step 1: Derive the Season Number
    ADMIN.sp_deriveSeasonNumber(v_SEASON_NUMBER_DERIVED);

    -- Step 2: Scan the LEAGUE_POOL table
    FOR r IN (SELECT lp.LEAGUE_POOL_ID, lp.LEAGUE_COUNTRY, lp.LEAGUE_LEVEL FROM LEAGUE_POOL lp) LOOP
        v_LEAGUE_COUNTRY := r.LEAGUE_COUNTRY;
        v_LEAGUE_LEVEL := r.LEAGUE_LEVEL;

        -- Step 3: Derive ALPHA2CODE_DERIVED and check for existing records
        CASE r.LEAGUE_COUNTRY
            WHEN 'Rest of Africa' THEN v_ALPHA2CODE_DERIVED := 'BJ';
            ELSE 
                -- Fetch from the COUNTRIES table
                SELECT ct.ALPHA2CODE INTO v_ALPHA2CODE_DERIVED
                FROM COUNTRIES ct WHERE ct.LEAGUE_COUNTRY = r.LEAGUE_COUNTRY;
        END CASE;

        -- Step 4: Check initial count to see if the league exists in current season
        SELECT COUNT(*) INTO v_count FROM LEAGUE_POOL_USERS lpu
        WHERE lpu.LEAGUE_POOL_ID = r.LEAGUE_POOL_ID AND lpu.SEASON_NUMBER = v_SEASON_NUMBER_DERIVED;

        IF v_count = 0 THEN
                SELECT COUNT(*) INTO v_count_plus 
                FROM LEAGUE_POOL_USERS 
                WHERE LEAGUE_POOL_ID = r.LEAGUE_POOL_ID AND SEASON_NUMBER = v_SEASON_NUMBER_DERIVED + 1;

                IF v_count_plus = 0 THEN
                -- Step 6: If the LEAGUE_POOL_ID doesn't exist in LEAGUE_POOL_USERS (and has not been added already to the next season), 
                -- THEN add NEW users to the database and create new leagues for new season
              sp_insertLeaguePoolUsers(v_SEASON_NUMBER_DERIVED, v_LEAGUE_COUNTRY, v_LEAGUE_LEVEL, r.LEAGUE_POOL_ID, v_ALPHA2CODE_DERIVED);
                END IF;

        ELSIF v_count > 0 THEN
               -- if it exists, check if the players have already been added to the next season to prevent duplication
            SELECT COUNT(*) INTO v_count_plus 
            FROM LEAGUE_POOL_USERS 
            WHERE LEAGUE_POOL_ID = r.LEAGUE_POOL_ID AND SEASON_NUMBER = v_SEASON_NUMBER_DERIVED + 1;   
            IF v_count_plus = 0 THEN
          -- Step 5: add all league levels to the next season
                CASE r.LEAGUE_LEVEL
                    WHEN 1 THEN
                        ADMIN.sp_handleleaguelevel1(v_SEASON_NUMBER_DERIVED, v_LEAGUE_COUNTRY);
                         WHEN 2 THEN
                        ADMIN.sp_handleLeagueLevel2(v_SEASON_NUMBER_DERIVED, v_LEAGUE_COUNTRY);
                        WHEN 3 THEN
                        ADMIN.sp_handleLeagueLevel3(v_SEASON_NUMBER_DERIVED, v_LEAGUE_COUNTRY);
                         WHEN 4 THEN
                        ADMIN.sp_handleLeagueLevel4(v_SEASON_NUMBER_DERIVED, v_LEAGUE_COUNTRY);
                END CASE; 
            END IF;
        END IF;
    END LOOP;

END lpUsers_master;

字符串
MySQL中的用户游标,但性能很糟糕

zrfyljdw

zrfyljdw1#

  • 一些小事情要做:使用EXISTS而不是COUNT。可能会快得多,而且可能永远不会慢。
IF v_count = 0 THEN
          SELECT COUNT(*) INTO v_count_plus 
          FROM LEAGUE_POOL_USERS 
          WHERE LEAGUE_POOL_ID = r.LEAGUE_POOL_ID
              AND SEASON_NUMBER = v_SEASON_NUMBER_DERIVED + 1;
          IF v_count_plus = 0 THEN  ...

字符串
-->

IF (v_count = 0) AND NOT EXISTS (
         SELECT 1 FROM LEAGUE_POOL_USERS 
            WHERE LEAGUE_POOL_ID = r.LEAGUE_POOL_ID
                AND SEASON_NUMBER = v_SEASON_NUMBER_DERIVED + 1 )
           THEN ...

  • 检查复合索引,它可能比单列索引快。
  • 4个sp_handleleaguelevel1进程可以合并吗?
  • 将处理过程从内向外翻转以避免光标。

相关问题