반응형
데이터베이스 성능 저하의 주요 원인은 비효율적인 쿼리 작성에 있습니다. 아래 주요 사례별로 문제 쿼리, 원인, 그리고 변경 쿼리를 제시합니다. 이를 참고해 쿼리 성능을 크게 개선할 수 있습니다.

1. SELECT * 사용으로 인한 불필요한 I/O 증가
문제 쿼리
SELECT *
FROM Sales.SalesOrderHeader
WHERE OrderDate >= '2025-01-01';
원인
- 테이블의 모든 컬럼을 가져와 불필요한 데이터 I/O와 네트워크 전송 비용이 발생
- 실제 필요한 컬럼을 명시하지 않아 SQL Server가 테이블 스캔 유도
변경 쿼리
SELECT OrderID, CustomerID, OrderDate, TotalDue
FROM Sales.SalesOrderHeader
WHERE OrderDate >= '2025-01-01';
반응형
2. 함수 사용으로 인한 인덱스 미사용
문제 쿼리
SELECT OrderID, OrderDate
FROM Sales.SalesOrderHeader
WHERE CONVERT(char(10), OrderDate, 120) = '2025-05-15';
원인
- 컬럼에 함수 적용 시 인덱스를 탈락시켜 전체 스캔 발생
- 변환 비용이 추가되어 CPU 부하 증가
변경 쿼리
SELECT OrderID, OrderDate
FROM Sales.SalesOrderHeader
WHERE OrderDate >= '2025-05-15'
AND OrderDate < '2025-05-16';
3. 커서(Cursor) 사용으로 인한 느린 반복 처리
문제 쿼리
DECLARE order_cursor CURSOR FOR
SELECT OrderID
FROM Sales.SalesOrderHeader;
OPEN order_cursor;
FETCH NEXT FROM order_cursor INTO @OrderID;
WHILE @@FETCH_STATUS = 0
BEGIN
-- 복잡한 처리 로직
FETCH NEXT FROM order_cursor INTO @OrderID;
END
CLOSE order_cursor;
DEALLOCATE order_cursor;
원인
- 행 단위 반복 처리로 수천~수만 건 처리 시 컨텍스트 스위칭 비용 상승
- 세트 연산을 활용하지 않아 전체 처리 시간이 비효율적
변경 쿼리
-- 예: 주문 상태별 집계 처리
SELECT OrderStatus, COUNT(*) AS OrderCount
FROM Sales.SalesOrderHeader
GROUP BY OrderStatus;
4. 조인 순서 및 불필요한 조인으로 인한 실행계획 비효율
문제 쿼리
SELECT C.CustomerID, O.OrderID, D.ProductID
FROM Sales.SalesOrderDetail D
JOIN Sales.SalesOrderHeader O ON D.SalesOrderID = O.SalesOrderID
JOIN Sales.Customer C ON O.CustomerID = C.CustomerID
WHERE D.OrderQty > 10;
원인
- 먼저 큰 테이블(D)에 필터가 적용되지 않아 조인 후 필터링
- 조인 순서가 비효율적으로 실행계획에서 비용 상승
변경 쿼리
SELECT C.CustomerID, O.OrderID, D.ProductID
FROM Sales.SalesOrderDetail D
-- 먼저 필터링하여 데이터를 줄임
WHERE D.OrderQty > 10
JOIN Sales.SalesOrderHeader O ON D.SalesOrderID = O.SalesOrderID
JOIN Sales.Customer C ON O.CustomerID = C.CustomerID;
5. 서브쿼리 대신 IN절/EXISTS절 미사용
문제 쿼리
SELECT OrderID, CustomerID
FROM Sales.SalesOrderHeader
WHERE CustomerID IN (
SELECT CustomerID
FROM Sales.Customer
WHERE TerritoryID = 5
);
원인
- IN절 내부에서 NULL 처리 및 중복 스캔으로 속도 저하
- 서브쿼리 재실행으로 인한 불필요한 비용
변경 쿼리
SELECT H.OrderID, H.CustomerID
FROM Sales.SalesOrderHeader H
WHERE EXISTS (
SELECT 1
FROM Sales.Customer C
WHERE C.CustomerID = H.CustomerID
AND C.TerritoryID = 5
);
6. TOP절에 ORDER BY 미지정으로 인한 예상치 못한 결과
문제 쿼리
SELECT TOP 100 *
FROM Sales.SalesOrderHeader;
원인
- 정렬 기준이 없어 랜덤한 100건을 가져와 안정적이지 않음
- 인덱스를 타고 가더라도 원하는 최신 데이터가 아닐 수 있음
변경 쿼리
SELECT TOP 100 *
FROM Sales.SalesOrderHeader
ORDER BY OrderDate DESC;
위 사례들을 참고해 불필요한 데이터 조회 최소화, 인덱스 활용을 방해하는 함수 제거, 반복 처리 대신 세트 연산, 적절한 조인 순서 및 필터링 우선 적용, EXISTS절 활용, 명확한 정렬 기준 지정 등을 적용한다면 MSSQL 쿼리 성능을 효과적으로 향상시킬 수 있습니다.
반응형
'● Data Insights > SQL' 카테고리의 다른 글
| SQL에서 Stored Procedure 사용 가이드 (0) | 2025.11.08 |
|---|---|
| SQL JOIN 가이드: 종류, 이론, 실전 예제와 최적화 (0) | 2025.11.03 |
| SELECT부터 ORDER BY까지: 읽기와 실행 순서 가이드 (3) | 2025.11.01 |
| (SQL Server) 고급 T-SQL 함수 활용 가이드: 핵심 요약 및 상세 예제 (0) | 2025.10.01 |
| (SQL Server) 시스템 로그 모니터링: AI 시대의 스마트 데이터베이스 관리 전략 (2) | 2025.09.29 |