database.sarang.net
UserID
Passwd
Database
DBMS
MySQL
PostgreSQL
Firebird
ㆍOracle
Informix
Sybase
MS-SQL
DB2
Cache
CUBRID
LDAP
ALTIBASE
Tibero
DB 문서들
스터디
Community
공지사항
자유게시판
구인|구직
DSN 갤러리
도움주신분들
Admin
운영게시판
최근게시물
Oracle Q&A 38859 게시물 읽기
No. 38859
비효율적인 쿼리 튜닝 부탁드립니다.
작성자
jinkuidong(jinkuidongjp)
작성일
2011-09-15 01:55ⓒ
2011-09-15 09:03ⓜ
조회수
6,334

 

사이트에서 많이 배우고 있습니다. 조언 부탁드립니다.

처리 내용은 일반유저가 처리할수 있는 데이타수와 다른유저에게 분양할수 있는 데이타수를 구하고자 합니다.

 

테이블 정보

t_recej 와 t_recek 는 1:M

t_recek 와 t_mosdk 는 1:M

 t_recej 의 PK 는 grpno

t_recek 의 PK 는 grpno + key

t_mosdk 의 PK 는 key + mdrno

 

PROCEDURE Excute

(

    in_deptcd        IN    CHAR,

    in_endymd        IN    CHAR,

    in_preymd        IN    CHAR

) IS

    CURSOR cUsers(pDeptCd CHAR) IS

        SELECT u.userid

          FROM m_users u

         WHERE u.deptcd = pDeptCd;

    vUsers m_users%ROWTYPE;

BEGIN

    OPEN cUsers(in_DeptCd);

    LOOP

        FETCH cUsers INTO vUsers;

        EXIT WHEN cUsers%NOTFOUND;

        vUserId := vUsers.userid;

        vEndYmd := in_endymd;

        vPreYmd := in_preymd;

        cDataCount(vUserId,vEndYmd, vPreYmd);

    END LOOP;

    CLOSE cUsers;

    COMMIT;

EXCEPTION

    WHEN OTHERS THEN

        ROLLBACK;

END Excute;

 

 

PROCEDURE countData

(

    in_userid        IN    CHAR,

    in_endymd        IN    CHAR,

    in_preymd        IN    CHAR

) IS 

    CURSOR cDataCount(pUserId CHAR, pEndYmd CHAR, pPreYmd CHAR) IS

        SELECT COUNT(DISTINCT DECODE(k.endymd, pEndYmd, m.key,'')) as usercnt

              ,COUNT(DISTINCT SELECT m1.key

                                FROM t_mosdk m1

                                    ,t_recek k1

                                    ,t_recej j1

                               WHERE m1.key      = m.key

                                 AND m1.mdrno    = m.mdrno

                                 AND m1.key      = k1.key

                                 AND k1.grpno    = j1.grpno

                                 AND NOT EXISTS

                                    (SELECT m2.key

                                       FROM t_mosdk m2

                                           ,t_recek k2

                                      WHERE m2.grpno    =  m1.groupno

                                        AND m2.key      =  k2.key

                                        AND m2.userid   <> pUserId

                                    )

                                 AND k1.status IN ('185','195')

                     ) AS managercnt

              ,COUNT(DISTINCT CASE WHEN k.status IN ('805''905') THEN DECODE(k.preymd, pPreYmd, m.key, '') END ) AS precnt

          FROM t_mosdk m

              ,t_recek k

              ,t_recej j

         WHERE k.grpno      = j.grpno

           AND m.key        = k.key

           AND m.grpno      = k.grpno

           AND m.userid     = pUserId

           AND(TRIM(k.endymd) IS NULL

               OR k.endymd = pEndYmd

               OR k.endymd = pPreYmd)

           AND k.status IN ('185','190','195','220','230','300','310','315','320','705','805','905');

    vDataCount cDataCount%ROWTYPE;

 

BEGIN

    OPEN cDataCount(in_userid, in_endymd, in_preymd);

    FETCH cDataCount INTO vDataCount;

    EXIT WHEN cDataCount%NOTFOUND;

    LOOP

        vUserCnt    := vDataCount.usercnt;

        vManagerCnt := vDataCount.managercnt;

        vPreCnt     := vDataCount.precnt;

        MERGE INTO t_sumcnt s

        USING (SELECT in_userid as userid FROM DUAL) m

        ON (s.userid = m.userid)

        WHEN MATCHED THEN 

            UPDATE SET s.usercnt     = vDataCount.usercnt

                      ,s.managercnt  = vDataCount.managercnt

                      ,s.precnt      = vDataCount.precnt

        WHEN NOT MATCHAED THEN

            INSERT (s.userid, s.usercnt, s.managercnt, s.precnt)

            VALUES (pUserId,  vUserCnt,  vManagerCnt,  vPreCnt );

    END LOOP;

CLOSE cDataCount;

EXCEPTION

    WHEN OTHERS THEN

        ROLLBACK;

END countData;

 

이 글에 대한 댓글이 총 2건 있습니다.

-- 대충 만들어서 헛점이 많을겁니다.  고쳐서 사용 바랍니다.

MERGE INTO t_sumcnt s
     USING (SELECT   u.userid
                    ,COUNT(DISTINCT DECODE(k.endymd, :pEndYmd, m.key, '')) AS usercnt
                    ,COUNT(
                        DISTINCT (SELECT m1.key
                                    FROM t_mosdk m1, t_recek k1, t_recej j1
                                   WHERE m1.key = m.key
                                     AND m1.mdrno = m.mdrno
                                     AND m1.key = k1.key
                                     AND k1.grpno = j1.grpno
                                     AND NOT EXISTS
                                            (SELECT m2.key
                                               FROM t_mosdk m2, t_recek k2
                                              WHERE m2.grpno = m1.groupno AND m2.key = k2.key AND m2.userid <> u.userid)
                                     AND k1.status IN ('185', '195')))
                        AS managercnt
                    ,COUNT(DISTINCT CASE WHEN k.status IN ('805''905') THEN DECODE(k.preymd, :pPreYmd, m.key, '') END)
                        AS precnt
                FROM t_mosdk m
                    ,t_recek k
                    ,t_recej j
                    ,(SELECT u.userid
                        FROM m_users u
                       WHERE u.deptcd = :pDeptCd) u
               WHERE k.grpno = j.grpno
                 AND m.key = k.key
                 AND m.grpno = k.grpno
                 AND m.userid = u.userid
                 AND (k.endymd IS NULL OR k.endymd = :pEndYmd OR k.endymd = :pPreYmd)
                 AND k.status IN ('185', '190', '195', '220', '230', '300', '310', '315', '320', '705', '805', '905')
            GROUP BY u.userid) m
        ON (s.userid = m.userid)
WHEN MATCHED THEN
   UPDATE SET s.usercnt = m.usercnt, s.managercnt = m.managercnt, s.precnt = m.precnt
WHEN NOT MATCHED THEN
   INSERT     (s.userid, s.usercnt, s.managercnt, s.precnt)
       VALUES (m.userid, m.usercnt, m.managercnt, m.precnt);

아무개님이 2011-09-15 17:11에 작성한 댓글입니다. Edit

 아무개님 답글 감사합니다. 

t_mosdk테이블과 t_recek데이블을 두번 읽었는데 한번 읽고 처리할수 있는 방법을 찿고 있습니다. 

inline query 를 사용하지 않는 방법은 없을까요.

 

jinkuidong(jinkuidongjp)님이 2011-09-15 17:35에 작성한 댓글입니다.
이 댓글은 2011-09-15 20:55에 마지막으로 수정되었습니다.
[Top]
No.
제목
작성자
작성일
조회
38862왜 더 느려지죠? [1]
김진국
2011-09-15
4473
388619/30정보 보호법 강화에 따른 개인정보 암호화...어떤 방식으로 진행하시나요 ??? [4]
궁금합니다.
2011-09-15
5384
38860where 절에서 in 구문.. [2]
아폴론
2011-09-15
4271
38859비효율적인 쿼리 튜닝 부탁드립니다. [2]
jinkuidong
2011-09-15
6334
38858유닉스 오라클에서 윈도우 서버 오라클로 이전 [3]
임두환
2011-09-14
5053
38857합계금액 추출 쿼리 질문 드려요 [5]
이순욱
2011-09-14
8543
38856시설사용신청 [1]
궁금합니다.
2011-09-14
4080
Valid XHTML 1.0!
All about the DATABASE... Copyleft 1999-2024 DSN, All rights reserved.
작업시간: 0.016초, 이곳 서비스는
	PostgreSQL v16.2로 자료를 관리합니다