공부, 기록

[MSSQL/SQL SERVER] 커서 본문

공부/DATABASE

[MSSQL/SQL SERVER] 커서

무는빼주세요 2022. 10. 3. 15:00

커서 : 일련의 데이터에 순차적으로 엑세스하여 처리가 필요할 때 사용한다. 커서를 사용하면 속도 문제등의 이슈를 겪을 수 있다. 커서는 임시테이블 또는 테이블 변수를 사용하여 처리가 가능하므로 커서의 사용을 지양해야 한다.

MSSQL 에서는 임시 테이블보단 테이블 변수의 사용이 성능상으로 더 이점이 있다. (물리 디스크와 메모리 I/O 차이)

그렇다면 왜 성능을 저하시키는걸까?

 

커서의 데이터 처리 방식

https://burning-dba.tistory.com/37

 

단순 쿼리와 커서의 차이점

단순 쿼리의 경우 SQL SERVER에서 실행계획이 생성되고 생성된 실행계획을 통하여 성능이 좋게 데이터를 읽을 수 있다.

SELECT  *
FROM    AdventureWorks2012.Sales.SalesOrderDetail
WHERE   ModifiedDate BETWEEN '2008-07-15 00:00:00.000' AND '2008-07-31 00:00:00.000'

해당 쿼리의 경우 ModifiedDate에 인덱스가 설정되어 있다면 또는 그렇지 않다해도 한번의 접근을 통해 데이터를 가져온다. (차후 실행될 경우에도 생성된 실행계획을 통하여 데이터를 읽는다)

 

하지만 이 쿼리를 다음과 같은 커서를 생성하여 읽을 경우 tempDB에 저장된 각 행에 대해 매번 접근을 해야하므로 성능적 이슈가 생긴다.

(해당 테스트의 경우 테이블은 1051건이었고 1초 미만의 시간이 걸린 쿼리가 50초 내외의 시간으로 소요가 됨)

DECLARE @rowguidVar UNIQUEIDENTIFIER  -- prepare unique ID variable to use in the WHERE statement below
 
DECLARE test_cursor CURSOR FOR  
SELECT rowguid
FROM   AdventureWorks2012.Sales.SalesOrderDetail
WHERE  ModifiedDate BETWEEN '2008-07-15 00:00:00.000' AND '2008-07-31 00:00:00.000'
--This is the same query as above except we SELECT only the ID for each row
 
OPEN test_cursor   
FETCH NEXT FROM test_cursor INTO @rowguidVar   
--This is the start of the cursor loop. 
WHILE @@FETCH_STATUS = 0   
BEGIN   
       SELECT *
          FROM            Sales.SalesOrderDetail
          WHERE    rowguid = @rowguidVar
-- Here we select on row and then move onto the next row ID and loop
       FETCH NEXT FROM test_cursor INTO @rowguidVar   
END
 
CLOSE test_cursor   
DEALLOCATE test_cursor
-- Don't forget these statements which flush the cursor from memory

커서의 메모리 사용

커서는 메모리를 차지하고 Lock을 사용하기 때문에 이로 인한 성능 이슈도 발생할 수 있다.

 

 

 

 

 

 

 

참조 : 

https://burning-dba.tistory.com/37

https://www.sqlshack.com/sql-server-cursor-performance-problems/

'공부 > DATABASE' 카테고리의 다른 글

[MySQL 8] 아키텍처-1  (0) 2022.12.24
[MySQL 8] 사용자 및 권한  (0) 2022.11.26
[MSSQL/SQL Server] 트랜잭션  (0) 2022.09.24
캐시와 실행계획  (0) 2022.05.21
[R&D]MongoDB  (0) 2022.03.16