데이터베이스 커서(Cursor)는 SQL 명령어를 사용하여 데이터베이스에서 데이터를 조회하고, 검색된 결과 집합을 한 행씩 처리할 수 있는 메커니즘이다.
장점
•
커서는 데이터베이스 관리 시스템(DBMS)에서 대량의 데이터 셋을 처리할 때, 또는 결과 집합을 반복적으로 읽고 조작해야 할 때 유용하다.
•
데이터베이스에 연결된 백엔드 응용프로그램에서 클라이언트 측 메모리를 절약할 수 있다.
Python, JavaScripts, Go 애플리케이션을 실행하고, 많은 결과를 처리하려는데 조금씩 처리하고 싶다면, 커서를 열고 100개의 행을 가져오기 시작할 수 있다. 다음 100개를 원한다면 메모리를 해제하고 다음 100개를 가져온다.
단점
•
커서를 공유할 수 없다.
•
수평적으로 확장하려면 커서를 사용할 수 없다.
•
서버간 커서 공유를 위해 DevOps 엔지니어가 커서 전달을 위한 변수를 처리할 수 있지만 굉장히 어렵다.
커서 예시
-- 커서 선언
DECLARE my_cursor CURSOR FOR
SELECT id, name FROM employees WHERE department = 'Sales';
-- 커서 열기
OPEN my_cursor;
-- 데이터를 가져오기 위한 변수 선언
DECLARE employee_id INT
DECLARE employee_name TEXT;
-- 데이터 가져오기
FETCH NEXT FROM my_cursor INTO employee_id, employee_name;
WHILE FOUND LOOP
-- 데이터를 처리하는 로직
RAISE NOTICE 'Employee ID: %, Name: %', employee_id, employee_name;
-- 다음 행 가져오기
FETCH NEXT FROM my_cursor INTO employee_id, employee_name;
END LOOP;
-- 커서 닫기
CLOSE my_cursor;
SQL
복사
import psycopg2
import time as t
con = psycopg2.connect(host="husseinmac",
database="husseindb",
user="postgres",
password = "postgres")
#client side cursor
s = t.time()
cur = con.cursor() # 서버측에서 실행하고 싶다면 이름을 입력해주면 됨.
e = (t.time() - s)*1000
print(f"Cursor established in {e}ms")
s = t.time()
cur.execute("select * from employees")
e = (t.time() - s)*1000
print(f"execute query {e}ms")
s = t.time()
rows = cur.fetchmany(50)
e = (t.time() - s)*1000
print(f"fetching first 50 rows {e}ms")
cur.close()
con.close()
Python
복사
클라이언트/서버 데이터베이스 커서
클라이언트 측 커서는 서버로부터 한 번에 모든 데이터를 가져오고, 로컬 메모리에서 데이터를 처리한다.
→ 전체 데이터 가져오는데 오래걸림. 이후, 예를 들어 50개씩 읽어오는 경우는 금방 가져옴.
서버 측 커서는 DB 서버에서 결과 집합을 유지하고, 클라이언트는 필요한 데이터만 서버로부터 가져간다.
→ 그때그때 가져오기에 메모리 활용에 장점이 있음.
•
네트워크 대역폭을 효율적으로 사용 가능.
특징 | 서버 측 커서(Server-Side Cursor) | 클라이언트 측 커서(Client-Side Cursor) |
메모리 사용 | 클라이언트 메모리 사용 최소화 | 클라이언트 메모리 사용 많음 |
데이터 접근 속도 | 네트워크 의존, 지연 발생 가능 | 로컬 메모리 접근, 빠름 |
독립성 | 네트워크 연결 필요 | 네트워크 의존도 낮음 |
업데이트 가능성 | 실시간 업데이트 가능 | 로컬 데이터만 처리, 실시간 업데이트 불가 |
복잡한 로직 처리 | 서버 측에서 처리 | 클라이언트 측에서 복잡한 처리 가능 |
네트워크 부하 | 네트워크 트래픽 증가 가능 | 네트워크 부하 최소화 |
동시성 문제 | 서버 측에서 동시성 문제 가능 | 동시성 문제 없음 |