SQL 작성 7거지악

2021. 4. 1. 00:03DB

좌변을 가공하지 않기

DB 인덱스를 사용할 수 없는 경우

  1. 인덱스 컬럼이 비교되기 전에 변형이 일어나는 경우
  2. 부정형으로 조건을 기술(not)한 경우
  3. 인덱스 컬럼이 NULL로 비교되는 경우
  4. 옵티마이저가 필요에 다라 상기 적용원칙을 준수했음에도 불구하고 특정 인덱스의 사용을 취사선택함으로써 사용되지 않는 경우

위와 같은 경우에 인덱스를 사용할 수 없습니다. 그렇기 때문에 DB 컬럼을 가공하지 말고 상수 부분을 가공해서 사용하도록 작성합니다.


잘못된 경우

-- 인덱스 컬럼에 변형이 일어났기 때문에 인덱스 사용이 불가

SELECT dept
     , ename
     , sal
  FROM emp
 WHERE SUBSTR(job, 1, 4) = 'SALE'

바람직한 경우

SELECT dept
     , ename
     , sal
  FROM emp
 WHERE job like 'SALE%'

 

데이터 존재 유무를 확인하기 위해 count(*) ... cnt > 0을 사용하지 않기

잘못된 경우

SELECT COUNT(*)
  FROM tbl_point
 WHERE user_id = 'id'

바람직한 경우

SELECT 1 AS cnt
 WHERE EXISTS (
                SELECT 'X'
                  FROM tbl_point
                 WHERE user_id = 'id'
              )

 

Decode 혹은 Case를 사용할 때 새끼를 증손자 이상 만들지 않기

 

증손자 이상으로 Decode와 Case를 사용하게 되면 연산자 계산에 cost가 발생해서 속도가 떨어집니다.

CASE WHEN(
          CASE WHEN(
                    CASE WHEN(...
                   )
         )

 

Union을 사용할 때 다시 한 번 Union all로 사용할 수 없는지 확인하기

 

Union all은 두개의 결과값에서 중복되는 결과값까지 출력합니다. 반면에 Union은 두 개의 결과값에서 중복되는 결과값을 제거하고 출력합니다. Union은 중복되는 결과값을 제거하기위해 내부적으로 sort가 발생하면서 distinct가 발생합니다.

 

In Line View 또는 out of temp를 사용할 때 진정 필요한 In Line View인지를 확인하기

 

Query -> Parse -> Query Rewrite -> Query Optimization -> QEP Generation -> Query Execution -> Result
SQL이 실행되면 위와 같은 순서로 결과를 생성합니다. 위 순서에서 Query Rewrite 단계에서 서브질의와 뷰의 병합이 수행됩니다.

Query 원문

SELECT emp_no 
  FROM 
             (
                SELECT
                   FROM emp
                 WHERE dept = ‘10’
             )
 WHERE emp_no > 20

Query Rewrite 단계

SELECT emp_no
  FROM emp
 WHERE dept = ‘10’
     AND  emp_no > 20

 

Join을 사용할 때 Relation 상 1:M, M:1, 1:1일 경우, 함부로 Outer Join을 사용하지 않기

 

Outer Join은 두 테이블 간의 관계에서 발생하는 조인 방식으로써 한쪽 테이블에 데이터가 없더라도 원래의 테이블 정보는 나오게 합니다. 이 때 Outer Join이 걸리는 테이블은 무조건 Full Table Scan이 발생합니다.

 

결과에만 만족하지 않고 실행계획에 관심을 가지고 절차형 로직을 버리고 집합적 하나의 SQL로 임무를 완수하기

 

모든 Query는 작성 후 실행계획을 확인해서 개발자가 원하는 형태로 수행이 되었는지 확인을 해 봐야 합니다. 인덱스가 생성 되어 있고 정상적인 연결고리로 조인이 이루어져도 옵티마이저에 의해 인덱스 취사와 같은 이유로 인덱스를 사용할 수 없는 경우도 발생할 수 있습니다. 그러므로 기본적으로 실행 계획은 확인하고 개발해야 합니다.

728x90

'DB' 카테고리의 다른 글

Elastic Search  (0) 2021.07.14
Dinstinct와 Group by의 차이  (0) 2021.05.03
MySQL Storage Engine  (0) 2020.11.25
DB Cluster  (0) 2020.11.20
MySQL Stored Procedure의 장단점  (0) 2020.09.17