1. Graph DB?
1) Summary : 데이터와 관계를 한번에 정리하여 여러 row의 관계상황을 빠르게 조회 가능한 데이터베이스
2) 사용 쿼리 언어 : Cypher, REST_API, SQL 등등
3) TABLE 종류
i. NODE : 엔티티 정보 저장
ii. EDGE : 관계 정보 저장
4) 대표적 도입 업체 : 페이스북, 카카오, Netflix
5) Graph DB 종류 :
2. 간단한 예제
1) 목적 : VOD – 점수 – VOD 로 연관된 데이터 추출
2) 테스트 데이터 : 타이틀번호(1), 타이틀번호(2), 학습된 연관 점수 19,697,444 건
3) 사용 GraphDB : SQL Server 2017 Enterpise
4) 테이블
i. GraphDB
A. NODE
중복을 제거한 vod 정보만 입력(611,942건의 VOD)
기본 검색을 위해 title_no에 CLUSTERED INDEX(정렬된 2진트리 INDEX) 생성
해당 node의 주소에 자동으로 NONCLUSTERED INDEX(정렬되지 않은 2진트리 INDEX)생성 - $node_id 로 사용
CREATE TABLE [dbo].[VodTitle](
[title_no] [bigint] NOT NULL,
PRIMARY KEY CLUSTERED
(
[title_no] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF,
ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
)
AS NODE ON [PRIMARY]
GO
-- 데이터 입력
INSERT [dbo].[VodTitle]
SELECT DISTINCT title_no_1 FROM zzz_vod_relation
UNION SELECT DISTINCT title_no_2 FROM zzz_vod_relation
B. EDGE
NODE 테이블의 ID 값으로 관계 정보 저장
빠른 조회를 위해 연결되는 시작점 node_id($from_id)에 CLUSTERED INDEX 적용
edge_id에 자동으로 NONCLUSTERD INDEX 생성
CREATE TABLE [dbo].[VodRelation](
[score] [float] NULL
)
AS EDGE ON [PRIMARY]
GO
CREATE CLUSTERED INDEX [IX_VodRelation] ON [dbo].[VodRelation]
(
$from_id
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF,
DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
GO
-- 데이터 입력
INSERT [dbo].[VodRelation]
SELECT A.$node_id
, C.$node_id
, B.score
FROM [dbo].[VodTitle] AS A
INNER JOIN [dbo].[zzz_vod_relation] AS B
ON A.title_no = B.title_no_1
INNER JOIN [dbo].[VodTitle] AS C
ON B.title_no_2 = C.title_no
ii. 퍼포먼스 비교를 위한 RDB
A. VOD 테이블(NODE 테이블 대응)
CREATE TABLE [dbo].[VodRelation_R](
[title_no_1] [bigint] NULL,
[title_no_2] [bigint] NULL,
[score] [float] NULL
) ON [PRIMARY]
GO
CREATE CLUSTERED INDEX [CIX_VodRelation_R] ON [dbo].[VodRelation_R]
(
[title_no_1] ASC,
[title_no_2] ASC,
[score] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF,
DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
GO
-- 데이터 입력
INSERT [dbo].[VodTitle_R]
SELECT DISTINCT title_no_1 FROM zzz_vod_relation
UNION SELECT DISTINCT title_no_2 FROM zzz_vod_relation
B. 관계 테이블(EDGE 테이블 대응)
CREATE TABLE [dbo].[VodRelation_R](
[title_no_1] [bigint] NULL,
[title_no_2] [bigint] NULL,
[score] [float] NULL
) ON [PRIMARY]
GO
CREATE CLUSTERED INDEX [CIX_VodRelation_R] ON [dbo].[VodRelation_R]
(
[title_no_1] ASC,
[title_no_2] ASC,
[score] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF,
DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
GO
-- 데이터 입력
INSERT [dbo].VodRelation_R
SELECT title_no_1
, title_no_2
, score
FROM [dbo].[zzz_vod_relation]
5) 예제 SELECT 쿼리 퍼포먼스 비교
SET STATISTICS TIME ON
SET STATISTICS IO ON
SET STATISTICS PROFILE ON
SELECT A.title_no
, B.title_no
, C.Score
FROM [dbo].[VodTitle] AS A, [dbo].[VodTitle] AS B, [dbo].[VodRelation] AS C
WHERE MATCH(A-(C)->B)
AND A.title_no = 40775406
SELECT A.title_no
, C.title_no
, B.Score
FROM dbo.VodTitle_R AS A
INNER JOIN dbo.VodRelation_R AS B
ON A.title_no = B.title_no_1
LEFT OUTER JOIN dbo.VodTitle_R AS C
ON B.title_no_2 = C.title_no
WHERE A.title_no = 40775406
SET STATISTICS PROFILE OFF
SET STATISTICS IO OFF
SET STATISTICS TIME OFF
i. 실행 비교
A. GraphDB :
< 매 시도 duration(단위 ms) : 2 >
B. RDB :
< 매 시도 duration(단위 ms) : 2>
C. 실행 계획 비용
A. 정규화 처리된 테이블 JOIN
B. 비졍규화 테이블 단독 INDEX 조회
D. 테스트 결론 :
A. 조회의 데이터 표본이 작아 결과 값으론 판단 어려움
B. 옵티마이저의 실행계획을 기준으로 비용 비교 시
GraphDB : RDB = 6 : 94
C. 데이터양이 많아질수록 관계형태가 존재하는 테이블에선 GraphDB 우위
D. 비정규화가 가능한 테이블에선
GraphDB : RDB = 98 : 2
E. 비정규화 하여 한 테이블에서 조회하는 것이 당연히 빠름(관계가 다양하지 않은 구조에선 비정규화 방법이 우위)
3. 결론
1) 데이터의 컬럼이 적을 경우 or 해당 데이터를 갱신하는 작업 적은 경우 비정규화된 테이블이 유리
2) 관계가 복잡하고 다양할수록 Graph 테이블이 유리
'Database > SQL Server' 카테고리의 다른 글
확장 이벤트를 통한 Dead Lock 캡처 (0) | 2021.04.22 |
---|---|
Lock 과 DeadLock (0) | 2021.04.22 |
Flyway 이용한 형상관리 (0) | 2021.04.16 |
SQL Server 및 OS 성능 지표 정리 (0) | 2021.04.16 |
SQL Server Monitoring (0) | 2021.04.14 |
최근댓글