Oracle/SQL2018. 3. 4. 10:04

랜덤 Top-N 쿼리를 작성해보자. 랜덤 Top-N 쿼리는 무작위로 정렬된 행의 상위 n건을 조회하는 쿼리다.


예제를 위해 아래와 같이 테이블을 생성하자.

-- 1
DROP TABLE t1 PURGE;
CREATE TABLE t1 AS SELECT LEVEL AS c1, LPAD ('X', 4000, 'X') AS c2 FROM DUAL CONNECT BY LEVEL <= 100000;


랜덤 Top-N 쿼리는 주로 DBMS_RANDOM.VALUE 함수를 사용하지만 Context Switching으로 인해 성능저하가 발생할 수 있다.

-- 2
SELECT c1
  FROM (SELECT   *
            FROM t1
        ORDER BY DBMS_RANDOM.VALUE)
 WHERE ROWNUM <= 5;

   C1
-----
13868
78870
95529
71122
60959

5 행이 선택되었습니다.

경   과: 00:00:02.25

10.1 버전부터 expr에 대한 해시 값을 반환하는 ORA_HASH 함수를 사용할 수 있다. max_bucket와 seed_value는 0 ~ 4294967295의 범위를 지정할 수 있다.

ORA_HASH (expr [, max_bucket [, seed_value ]])


아래 쿼리는 DBMS_RANDOM.VALUE 함수 대신 ORA_HASH 함수를 사용했다. DBMS_RANDOM.VALUE 함수에 비해 소요시간이 감소한 것을 확인할 수 있다.

-- 3
SELECT c1
  FROM (SELECT   *
            FROM t1
        ORDER BY ORA_HASH (c1, TO_CHAR (SYSTIMESTAMP, 'FF9'), TO_CHAR (SYSTIMESTAMP, 'FF9')))
 WHERE ROWNUM <= 5;

   C1
-----
87694
57914
93642
38203
43376

5 행이 선택되었습니다.

경   과: 00:00:00.79


테이블 사이즈가 크다면 SAMPLE 절 사용을 고려할 수 있다. 블록 샘플링 방식과 적절한 sample_percent를 지정해야 한다. 아래 쿼리에서 소요시간이 급격히 감소한 것을 확인할 수 있다.

-- 4
SELECT c1
  FROM (SELECT   *
            FROM t1 SAMPLE BLOCK (1)
        ORDER BY ORA_HASH (c1, TO_CHAR (SYSTIMESTAMP, 'FF9'), TO_CHAR (SYSTIMESTAMP, 'FF9')))
 WHERE ROWNUM <= 5;

    C1
-----
22897
55394
22883
55367
89560

5 행이 선택되었습니다.

경   과: 00:00:00.04


'Oracle > SQL' 카테고리의 다른 글

NLS_DATE_FORMAT 파라미터와 데이터 변환  (0) 2018.09.01
날짜 기간 조회  (0) 2018.03.07
수열 생성  (0) 2018.03.03
테이블 동기화  (0) 2018.01.18
근태 내역 조회  (0) 2014.07.29
Posted by 정희락_