본문 바로가기
데이터인문학/데이터스토리

SQL 최적화 쿼리 만들기 | Query 간 주의할 7가지

by 데이터스토리 2024. 10. 16.
반응형

SQL로 최적화된 쿼리를 만들 때 주의할 사항입니다. 쿼리는 아주 좋은 데이터 처리 언어입니다. CRUD라 불리는 데이터 생성, 조회, 수정, 삭제 작업을 진행할 수 있죠. 게다가 SQL은 구조적 언어이므로 RDB에 최적화되어 있습니다. 하지만, 사용할 때 쿼리 성능을 위해 주의해야 할 사항이 있으니 고려하여 사용하세요.

 

 

주의사항 7가지

 

많은 회사가 클라우드에서 데이터를 처리하고 저장하기에 쿼리 최적화는 회사의 IT비용에 영향을 준다. 이에 쿼리 최적화 작업은 비용을 줄이고 효율을 높이는 작업이다.

 

1. 와일드카드(% 또는 _ ) 사용 자제하기

  • 와일드카드는 전체 테이블 스캔이 필요할 수 있기에, 쿼리 성능을 떨어트린다.
  • 조건식에서 와일드카드 사용을 줄여 쿼리 성능을 올리도록 하자. 
-- 기존 > 
  Select * from emp where first_name like 'K%';

-- 개선   
  Select * from emp where first_name >= 'K' and first_name >= 'L' ;

 

 


 


 

2. 하위 쿼리 사용하지 않기

하위 쿼리는 Select 문 안에 또 다른 Select 문이 있는 경우이다.

이는 쿼리 성능을 상당히 저하시킨다. (가능성이 높다)

이유는 하위 쿼리를 먼저 수행 후 그 결과를 본 쿼리에 다시 반영하는 이중적인 쿼리 수행 때문이다.

대신, JOIN이나 임시 테이블을 사용하면 효율을 높일 수 있다.

이런 Join이나 임시 테이블 사용은 비즈니스 및 데이터 처리 프로세스에 대한에 대한 지식이 갖추어졌을 때 유용하다. 

 

아래 예시를 보자

[요구사항] 최근 일주일 동안 주문한 모든 고객 정보 조회

-- 하위 쿼리 이용 ----
SELECT  *  
  FROM  customer 
 WHERE  customer_ID IN ( SELECT customer_ID 
                       FROM order 
                      WHERE order_date >= DATEADD( Day , -7 , GETDATE()));
                     
-- 개선" JOIN 사용 ----
SELECT  DISTINCT c. *  
  FROM  customers c 
        JOIN orders o ON c.customer_id = o.customer_id 
 WHERE  o.order_date >= DATEADD( day , -7 , GETDATE());

 

하위쿼리 대신 JOIN을 이용하여 결과를 처리하였다. 속도는 분명 빠를 것이다. 데이터 양이 많다면 더욱더 빠를 것이다.

 

 

mysql Visual Database Design
SQL 최적화 쿼리 만들기 ❘ Query 간 주의할 7가지

 

 

 

 

 

3. 전체 요청 대신 "LIMIT" 또는 "TOP"을 사용하라

보통 "Select * from Table" 쿼리를 많이 사용한다. 하더라도 전체보다는 제한적인 결과를 돌려준다

이유는 쿼리 작성하는 툴에서 제어를 해 주기 때문이다.(Dbeaver 같은) 

하지만, 쿼리를 최적화하려면 LIMIT(MySQL의 경우) 또는 TOP(SQL Server의 경우)을 사용하여 반환되는 행 수를 제한하는 주의가 필요하다. 전체 데이터 필요 없는 경우가 많기 때문에 필수 데이터에만 집중하자.

 

아래 예시를 보자

[요구사항] 최근 90일 동안 주문한 모든 고객 정보 조회

 

위 요구사항의 결과는 아주 많은 양이 될 것이다. 하지만, 데이터를 확인하기 위해서는 전부가 필요하지 않은 경우가 많다. 이럴 때는 아래와 같이 "TOP 10"(또는 LIMIT 10)으로 제한을 걸어 일부만 가져와서 살펴보는 게 효율이 더 좋다.

SELECT TOP 10  *  
  FROM customers 
 WHERE customer_id IN 
       ( SELECT customer_id 
           FROM orders 
          WHERE order_date >= DATEADD( day , -90 , GETDATE()));

 


 


 

 

4. SELECT * 자제하기

우리가 자주 또는 무의식으로 사용하는 쿼리가 있다.

"Select * From Table"이다. 정말 많이 사용한다. 이유는 빠르게 코딩할 수 있기 때문이다. 

하지만 우리가 필요한 것은 모든 열이 아니다. 필요한 열은 제한적일 경우가 많다. 그러니 쿼리 할 때, 보고자 하는 열을 지정하여 쿼리 하도록 하자.

이는 불필요한 데이터 검색 자원을 줄이고, 데이터 추출을 위한 쿼리 효율성이 높여지게 된다.

 

아래 예시를 보자

[요구사항] 최근 90일 동안 주문한 모든 고객 정보 중 "id, 이름, 성"을  조회

 

customer 테이블의 전체 칼럼이 아닌 필요한 부분인 "id, 이름, 성"만 추출합니다.

 

-- 기존

SELECT  *  
  FROM  customer 
 WHERE  customer_ID IN 
        ( SELECT customer_ID 
            FROM order 
           WHERE order_date >= DATEADD( day , -90 , GETDATE()));
           
 -- 수정
 SELECT customer_ID, first_name, last_name 
   FROM customer 
  WHERE customer_ID IN 
         ( SELECT customer _ID 
             FROM order 
             WHERE order_날짜 >= DATEADD( day , -90 , GETDATE()));

 

 

 

 

5. IN보다 EXISTS를 사용하라

IN은 하위 쿼리 내에서 전체 테이블 스캔을 한다. 그러니 오래 걸리게 된다. 데이터가 많

EXISTS는 IN 보다 더 좋은 성능을 보인다.

하위 쿼리에 IN 대신 EXISTS를 사용하여 성능을 향상하자.

EXIST구문은 하위쿼리 결과가 있는지 여부를 보여준다. 

 

- EXISTS: 특정 칼럼값이 존재하는지 여부를 확인
- IN: 괄호 안의 값 혹은 서브쿼리의 결과가 포함되는지 여부를 확인
SELECT *
  FROM dept a
 WHERE a.deptno IN (1000, 2000, 3000)
   AND EXISTS (SELECT 1
                 FROM emp b
                WHERE b.sal between 500 and 1300
                  AND b.deptno = a.deptno)

 

 

 

데이터베이스 중에 많이 사용하는 것 중 하나인 MySQL입니다. 아래는 MySQL의 튜토리얼입니다. 학습에 도움 되실 것입니다. 한 번씩 내용 보시기 바랍니다.

 

[youtube] MySQL Workbench Tutorial

 

 

6. 데이터베이스 설계 최적화 및 데이터 정규화 준수

데이터베이스 스키마가 최적화되고 정규화 원칙을 따르도록 합니다. 이렇게 하면 중복을 최소화하고 쿼리 효율성을 개선하여 데이터 무결성과 쿼리 성능이 향상됩니다.

 



 

7. 인덱싱 사용

WHERE, JOIN, ORDER BY 절에서 자주 사용되는 열에 인덱스를 만듭니다. 인덱스는 데이터베이스 엔진이 관련 행을 빠르게 찾을 수 있도록 하여 더 빠른 데이터 검색을 용이하게 합니다.

 

 

 

[블로그] MySQL 블로그 | 오라클

 

Oracle Blogs | The Oracle MySQL Blog

 

blogs.oracle.com

 

 

 

참조 링크

 

   SQL 쿼리 최적화 기술

 

  더 빠른 성능을 위한 SQL 쿼리 최적화를 위한 12가지 팁

 

12 Tips for Optimizing SQL Queries for Faster Performance

Ways to Optimize SQL Queries

medium.com

 

 

반응형