[Oracle Database] SQL의 WITH 문장 사용 방법 및 사용 방법

6947 단어 SQLOraclewithtech

WITH 문장의 역할


WITH 문장은 표준 SQL 표준에서도 정의(SQL99 이후)[1]가 있다.이에 따라 SQL Server, PostgreSQL, MySQL(MarriadB)도 이용할 수 있다.
SELECT 문장 등 DML의 첫머리에는 일시적인 VIEW나 PROCEDURE를 정의하는 데 사용되며 SQL의 가독성을 높이는 장점이 있다.사용법에 따라 처리 속도 향상도 기대할 수 있다.
Oracle Database(이하 Oracle)에서 다음 작업을 수행할 수 있습니다.
  • DML과 함께 임시 VIEW 정의
  • DML과 함께 임시 PROCEDURE, FUCTION
  • 정의
    나는 응용 프로그램을 개발할 때 사용할 기회가 매우 적다고 생각한다.WITH 문장이 활발한 장면은 아마도 데이터 추출 업무처럼 사용자가 DB 참조 권한만 부여받았을 때일 것이다.
    참조 권한만 있을 경우 VIEW 또는 스토리지 주소를 만들 수 없습니다.이 경우 WITH 문장을 아는 것이 편리하다.

    사용법


    1. VIEW 만들기


    SQL은 다음과 같습니다.
    WITH V_MANAGER AS (SELECT *
                         FROM EMP
                        WHERE JOB = 'MANAGER')  
    SELECT *
      FROM V_MANAGER
    
    결과는 다음과 같다.
    テンポラリなVIEWの定義
    그나저나 오라클 라이브 SQL은 무료로 이용할 수 있고, 오라클에서 유명한 샘플 데이터(HR, EMP 등)도 간단하게 준비(※ 계정은 무료로 만들 수 있음)할 수 있으니 연습하고 싶은 분은 이용하세요.
    Oracle Live SQL

    2. 프로듀서, FUCTION 만들기


    FUCTION을 WITH 문구로 정의하면 안내문을 쓰지 않아도 되기 때문에 주체의 SELECT 문을 간결하게 쓸 수 있다.
    다만, 원래 SELECT 문구의 기록수가 방대하면 처리 속도가 지연된다고 부문의에서 일반적으로 말할 수 있다.따라서 사용하는 곳은 주의해야 한다.
    FUTION을 사용할 때는 다음과 같습니다.
    WITH
      --採用日が87年以降かどうかを判定するFUNCTION
      FUNCTION F_HIREDATE(DT IN DATE)
      RETURN VARCHAR2
      AS
      BEGIN
        RETURN CASE WHEN TO_CHAR(DT,'YY') > 86 THEN '○'
               ELSE '×'
               END;
      END;
      
     --本体のSELECT文
     SELECT ENAME    AS "名前"
           ,HIREDATE AS "採用日"
           ,F_HIREDATE(HIREDATE) AS "87年以降"
       FROM EMP
    
    결과는 이렇다.
    WITH句でFUNCTIONを定義

    WITH 사용: 내부 VIEW 제작으로 응답 속도 향상


    WITH 문장으로 VIEW를 만들면 DB 서버 옆에서 임시 테이블을 만드는 동작을 한다(optimather가 판단하기 때문에 반드시 만들어지는 것은 아니다).
    호스트의 DML에서 같은 VIEW를 여러 번 참조할 때나 부조회에서 모든 음반을 같은 VIEW를 여러 번 참조할 때 성능이 향상되었다[2].
    다음은 단지 실체의 SELECT 문으로 V_EMP의 VIEW를 여러 번 참조하고 있다.집행 계획을 보면 내부에 느슨한 탁자가 만들어져 있다는 것을 알 수 있다.
    WITH
      V_EMP AS (
      SELECT JOB, SUM(SAL) AS SAL_SUM
        FROM EMP
       GROUP BY JOB)
       
    SELECT * FROM V_EMP WHERE JOB = 'MANAGER'
    UNION ALL
    SELECT * FROM V_EMP WHERE JOB = 'CLERK'
    
    집행 계획은 다음과 같다.
    SYS_TEMP_0FD9D68B3_이것은 내부에 229C55를 만드는 임시 표입니다.

    이것은 부문의 상황에서도 같은 효과를 기대할 수 있다(SQL의 효율에 대해서는 반드시 집행계획을 보고 판단해야 한다).

    PROCEDURE, FUCTION 사용 시 성능 고려


    코드 구분 변환 등에 사용할 수 있지만 N+1 문제와 같은 경우(부문의도 마찬가지)가 발생할 수 있다.
    코드의 가독성은 향상됐지만, 성능 면에서는 비효율적일 수 있으니 주의가 필요하다.주 시스템만 구분한다면 결합 처리가 더욱 효율적일 것이다.
    다만, SQL 튜닝은 실행계획을 보면서 판단해야 하므로 매번 검증하는 것이 좋다.

    기타


    .NET의 EntyFramework는 WITH 문을 지원하지 않습니다.
    파이톤의 SQL Alchemy가 아직 확인되지 않았습니다. (매뉴얼에서 보면 지원되는 것 같습니다.)
    다만, 원래는 ORM이라면 내부 VIEW를 만들면 WITH와 같을 수 있기 때문에 신경 쓸 필요가 없다.
    각주
    "자상지향, 자바의 새로운 업계 표준""SQL99""상세 설명"(@IT)
    https://www.atmarkit.co.jp/fnetwork/tokusyuu/01sql99/sql99_1b.html ↩︎
    진도 박사에 대한 퍼포먼스 강좌 제11회 좋은 SQL(2)
    https://blogs.oracle.com/otnjp/tsushima-hakushi-11 ↩︎

    좋은 웹페이지 즐겨찾기