

 Amazon Redshift는 패치 198부터 새 Python UDF 생성을 더 이상 지원하지 않습니다. 기존 Python UDF는 2026년 6월 30일까지 계속 작동합니다. 자세한 내용은 [블로그 게시물](https://aws.amazon.com/blogs/big-data/amazon-redshift-python-user-defined-functions-will-reach-end-of-support-after-june-30-2026/)을 참조하세요.

# Amazon Redshift 쿼리 설계 모범 사례
<a name="c_designing-queries-best-practices"></a>

쿼리 성능을 극대화하려면 쿼리 생성 시 다음 권장 사항을 따르십시오.
+ 쿼리 성능을 높일 수 있는 탄탄한 기반을 완성하려면 모범 사례에 따라 테이블을 설계하십시오. 자세한 내용은 [Amazon Redshift 테이블 설계 모범 사례](c_designing-tables-best-practices.md) 섹션을 참조하세요.
+ `select *` 사용은 피하십시오. 그리고 반드시 필요한 열만 추가하십시오.
+ 동일한 테이블에서 반복적으로 선택하지 말고 [CASE 조건식](r_CASE_function.md)을 사용하여 복합적인 집계를 실행하십시오.
+ 절대적으로 필요한 경우가 아니라면 크로스 조인을 사용하지 마십시오. 이 조인 방법은 조인 조건이 없기 때문에 두 테이블의 데카르트 곱이 발생하는 원인이 됩니다. 크로스 조인은 일반적으로 중첩 루프 조인으로 실행되기 때문에 가능한 조인 유형 중에서 속도가 가장 느립니다.
+ 쿼리에서 한 테이블만 조건자 조건에 사용되는 경우에는 하위 쿼리를 사용하십시오. 그러면 하위 쿼리가 소수의 행(약 200개 미만)을 반환합니다. 다음은 하위 쿼리를 사용하여 LISTING 테이블을 조인하지 않는 예입니다.

  ```
  select sum(sales.qtysold)
  from sales
  where salesid in (select listid from listing where listtime > '2008-12-26');
  ```
+ 조건자를 사용하여 최대한 많은 데이터 세트를 제한하십시오.
+ 술어에서 할 수 있는 가장 비용이 적게 드는 연산자를 사용하십시오. [비교 조건](r_comparison_condition.md) 연산자는 [LIKE](r_patternmatching_condition_like.md) 연산자보다 바람직합니다. 그리고 LIKE 연산자는 [SIMILAR TO](pattern-matching-conditions-similar-to.md) 또는 [POSIX 연산자](pattern-matching-conditions-posix.md)보다 효과적입니다.
+ 쿼리 조건자에서 함수 사용은 자제하십시오. 함수를 사용하면 쿼리의 중간 단계 해결을 위해 엄청난 수의 행이 필요하기 때문에 쿼리 비용이 더욱 커질 수 있습니다.
+ 가능하다면 WHERE 절을 사용하여 데이터 세트를 제한하십시오. 그러면 쿼리 플래너가 기준과 일치하는 레코드를 결정하는 데 행 순서를 사용할 수 있기 때문에 엄청난 수의 디스크 블록을 스캔하는 단계를 건너뛸 수 있습니다. 이렇게 하지 않으면 쿼리 실행 엔진이 포함되어 있는 열을 모두 스캔해야 합니다.
+ 동일한 필터가 적용되는 조건자라고 해도 조건자를 추가하여 조인에 참여하는 테이블을 필터링하십시오. 쿼리는 동일한 결과 집합을 반환하지만 Amazon Redshift는 스캔 단계 전에 조인 테이블을 필터링 할 수 있으므로 이러한 테이블에서 검색 블록을 효율적으로 건너 뛸 수 있습니다. 조인 조건에 사용되는 열을 기준으로 필터링하는 경우에는 중복 필터가 필요하지 않습니다.

  예를 들어 `SALES` 테이블과 `LISTING` 테이블을 조인하여 12월 이후 판매자별로 목록에 나열된 티켓의 판매량을 찾으려고 한다고 가정하겠습니다. 그리고 두 테이블은 날짜를 기준으로 정렬되어 있습니다. 다음 쿼리는 공통 키를 통해 두 테이블을 조인한 후 12월 1일보다 더 큰 `listing.listtime` 값을 필터링합니다.

  ```
  select listing.sellerid, sum(sales.qtysold)
  from sales, listing
  where sales.salesid = listing.listid
  and listing.listtime > '2008-12-01'
  group by 1 order by 1;
  ```

  WHERE 절에는 `sales.saletime` 조건자가 없기 때문에 실행 엔진이 전체 `SALES` 테이블을 강제로 스캔해야 합니다. 이때 필터링을 통해 조인에 참여하는 행의 수가 줄어든다는 사실을 알고 있다면 필터 역시 추가할 수 있습니다. 다음은 실행 시간을 크게 줄일 수 있는 예입니다.

  ```
  select listing.sellerid, sum(sales.qtysold)
  from sales, listing
  where sales.salesid = listing.listid
  and listing.listtime > '2008-12-01'
  and sales.saletime > '2008-12-01'
  group by 1 order by 1;
  ```
+ 쿼리 플래너의 집계 효율을 높일 수 있도록 GROUP BY 절에 정렬 키를 사용하십시오. GROUP BY 목록에 정렬 키 열만 포함되어 있으면(이중 하나는 분산 키임) 쿼리 실행 시 1단계 집계가 가능합니다. GROUP BY 목록의 정렬 키 열에는 1차 정렬 키를, 그리고 정렬 키 순서에 사용할 다른 정렬 키를 추가해야 합니다. 예를 들어 1차 정렬 키, 1차/2차 정렬 키, 1차/2차/3차 정렬 키 등을 사용하는 것이 유효합니다. 1차/3차 정렬 키를 사용하는 것은 유효하지 않습니다.

  1단계 집계의 사용 여부는 [EXPLAIN](r_EXPLAIN.md) 명령을 실행한 후 쿼리의 집계 단계에서 `XN GroupAggregate`를 찾아보면 확인할 수 있습니다.
+ GROUP BY 절과 ORDER BY 절을 동시에 사용하는 경우에는 두 절 모두 동일한 순서대로 열을 삽입해야 합니다. 즉, 다음과 같은 접근법을 사용하십시오.

  ```
  group by a, b, c
  order by a, b, c
  ```

  다음과 같은 접근법을 사용하지 마십시오.

  ```
  group by b, c, a
  order by a, b, c
  ```