tech Neo4j Query Performance 톺아보기
2023.04.14 14:32- 작성자 관리자
- 조회 1,990
Neo4j Query Performance 톺아보기
- DSC 전종희 선임 -
안녕하세요, 엔코아 DSC에서 그래프 데이터베이스 관련 4번째 블로그 글을 게시합니다.
4번째 게시글 주제는 Neo4j에서 그래프 데이터 질의 성능과 관련된 Query Performance와 관련된 부분에 대해서 알아보도록 하겠습니다.
일반적으로 데이터베이스 성능이라고 하면 구성된 데이터베이스 자원으로 사용자 질의에 대해 최적의 질의 응답속도를 얻을 수 있는지에 대해 의미를 가지게 됩니다. 데이터베이스 성능을 고려할 수 있는 측면으로 데이터 모델링·DBMS·SQL·H/W 관점 등 다양한 항목들이 있습니다.
이 중에서 SQL을 통한 성능 개선은 옵티마이저, 힌트, 인덱스 등을 통해 성능 향상을 도모하게 됩니다.
SQL이 실행되기 위해서는 실행 가능한 소스코드로 변환되어야 합니다. 이 소스코드를 생성하기 위한 실행 전략을 실행 계획이라고 합니다. 옵티마이저는 실행 계획을 수립하기 위해 SQL을 관계 대수 형태로 변환하고 개별 연산자의 알고리즘들을 다양한 방법으로 결합해 이들을 트리 형태로 표현합니다.
그림 1 오라클 SQL 트레이스 기능
실행 계획 분석이란, 옵티마이저의 한계를 인식하고 옵티마이저가 최적화된 실행 계획을 수립할 수 있도록 유도하는 데 목적이 있으며 방법은 DBMS 별로 약간 차이가 있지만 상용 혹은 DBMS 벤더가 제공하는 SQL 개발 도구를 사용하면 쉽게 실행 계획 보기를 수행할 수 있습니다.
https://dataonair.or.kr/db-tech-reference/d-guide/da-guide/?mod=document&uid=304
본 게시물의 목차는 아래와 같습니다
ㆍNeo4j Query Processing Workflow
ㆍNeo4j 실행계획
ㆍNeo4j Index
ㆍNeo4j Query Processing Workflow
Neo4j의 Query Performance 방법을 알아보기 전에 기존 RDBS와 Neo4j 쿼리 수행 절차가 어떻게 되는지 보도록 하겠습니다. 아래는 우리가 익숙한 RDBMS(Oracle)의 쿼리 수행 절차입니다.
그림 2 오라클 SQL 처리 절차(https://docs.oracle.com/database/121/TGSQL/tgsql_sqlproc.htm#TGSQL178)
사용자에게 SQL 질의문을 입력 받아 파싱 단계에서 문법 체크와 구문 분석을 수행하고 Soft Parse 또는 Hard Parse를 거쳐 해당 SQL문을 옵티마이저가 최적의 실행 계획을 세우고 그 결과를 바탕으로 SQL이 수행되고 Fetch 단계에서 결과값을 산출 및 반환하는 흐름으로 진행됩니다.
그림 3 Neo4j Query Processing Workflow (https://neo4j.com/graphacademy/training-cqt-40/01-cqt-40-how-queries-work-in-neo4j/)
Neo4j의 쿼리 수행 절차도 기존 RDBMS와 유사하다고 볼 수 있습니다. Cypher 질의문을 입력 받아 파싱하여 이를 토큰화한 다음 Cypher 질의문의 문법과 의미 분석을 수행합니다.
그림 4 좌측부터. 구문트리 / 플래너/ 실행계획 예시
구문 트리를 통해 문법과 의미 분석이 수행되며 최적화된 구문 트리를 기반으로 Planner에 의해 논리적·물리적 실행 계획이 생성되고 사용자 질의에 따른 결과를 반환하는 절차로 수행됩니다.
ㆍNeo4j 실행계획
Neo4j 실행계획은 쿼리를 정의한 텍스트에서 플래너(Planner)라는 Cypher의 구성 요소에 의해 결정되며 비용 기반 플래너가 기본으로 적용되어 있습니다.
쿼리 옵션 | 설명 | 기본 |
Planner=cost | 계획 검색 공간 및 시간에 대한 기본 제한이 있는 비용 기반 계획을 사용합니다 | ○ |
Planner=idp | Planner=cost와 동일 | |
Planner=dp | 계획 검색 공간과 시간에 대한 제한 없이 비용 기반 계획을 사용하여 최상의 실행 계획을 통한 검색 수행 * 해당 옵션을 사용하면 쿼리 계획 시간이 크게 늘어날 수 있음 |
https://neo4j.com/docs/cypher-manual/current/execution-plans/db-hits/
비용 기반 플래너는 쿼리 실행 시 업데이트 된 통계 정보를 비용이 더 저렴한 쿼리를 선택하게 됩니다.
실행계획을 확인하는 방법으로 EXPLAIN과 PROFILE이 있으며, EXPLAIN은 쿼리를 실행하지 않고 실행 계획을 제공합니다. db hits가 없으며 대략적인 행의 수만 추정하여 확인할 수 있습니다. PROFILE은 쿼리를 직접 실행한 후 결과를 반환하며 db hits수와 행의 수가 포함되어 확인할 수 있습니다.
db hits는 사용자 또는 운영자가 데이터 검색 및 업데이트와 같은 작업을 수행할 때 스토리지 엔진에 요청을 보내게 되는데 이때의 요청이 처리되는 작업의 추상 단위입니다. 해당 요청의 작업들은 Create·Delete·Update·Node-Specific·Relationship-specific·Schema 등이 있습니다.
https://neo4j.com/docs/cypher-manual/current/execution-plans/db-hits/
그림 5 EXPLAIN 예시
EXPLAIN 옵션을 Cypher 쿼리 앞에 선언하면 해당 쿼리에 대한 실행계획을 확인할 수 있습니다. 실행 절차마다 대략적인 행의 수만 확인됩니다.
그림 6 PROFILE 예시
PROFILE 옵션을 Cypher 쿼리 앞에 선언하면 해당 쿼리에 대한 실행계획을 확인할 수 있으며, 실행 절차마다 다양한 통계정보와 각 단계의 행 수도 확인할 수 있습니다.
그림 7 Cypher Text 실행계획 예시
실행계획을 시각적으로도 확인할 수 있지만 위의 그림처럼 텍스트 형태의 실행계획도 확인할 수 있습니다.
ㆍNeo4j Index
Neo4j에서 인덱스는 Cypher 쿼리에서 조회하고자 하는 관련 데이터의 시작점 보다 효율적으로 검색하고 찾는데 사용됩니다. 인덱스를 생성한다는 것은 추가 저장 공간과 쓰기 비용을 초래할 수 있으므로 인덱싱할 항목을 결정하는 것은 중요한 요소로 작용할 수 있습니다.
인덱스가 생성되면 DBMS에서 관리하고 최신 상태로 유지합니다. Neo4j는 인덱스가 생성되고 온라인 상태가 되면 자동으로 인덱스를 선택하고 사용합니다.
인덱스 생성 방법 - CREATE INDEX ON :LabelName(propertyName)
그림 8 인덱스 생성 예시
인덱스 강제 사용에 대한 HINT는"USING" 키워드를 이용하여 선언할 수 있습니다.
MATCH (t:Tower {name: “”}} USING INDEX t:Tower(name)
|
MATCH (t:Tower:Location} USING SCAN t:Tower WHERE <Label Hint> |
Neo4j v4 까지 사용되던 BTREE(Balanced TREE) 인덱스는 Neo4j v5 에서 제거되면서 RANGE와 TEXT / POINT 인덱스로 대체 되었습니다.
그림 9 RDB의 BTREE 인덱스 구조 예시(https://dataonair.or.kr/db-tech-reference/d-guide/sql/?mod=document&uid=366)
BTREE 인덱스는 속성을 노드 또는 관계에 매핑하여 모든 유형에 대하여 인덱스 조회를 수행하며 대부분의 다른 데이터베이스에 공통적으로 널리 사용되는 구조 중 하나이기도 합니다.
RANGE 및 TEXT 인덱스는 정확한 일치, 접두사, 하위 문자열 또는 접미사 일치와 같은 문자열에 대해 제한된 일치만 수행할 수 있습니다. 대신 FULL-TEXT 인덱스는 인덱싱 된 문자열 값을 토큰화 하므로 문자열 내 어디에서나 용어를 일치시킬 수 있습니다.
✔ LOOKUP 인덱스
◽ 기본으로 제공되는 인덱스이며 노드 레이블과 관계 타입에 대해 적용됩니다.
◽ LOOKUP 인덱스는 Cypher 쿼리와 다른 인덱스의 성능을 향상시키기 때문에 매우 중요한 인덱스이며 삭제 할 시에 심각한 성능 저하가 발생할 수 있습니다.
ex) MATCH (n:Label) , MATCH (n) WHERE n:Label, MATCH ()-[r:REL]->()
✔ RANGE 인덱스
◽ RANGE 인덱스는 노드 레이블과 관계 타입 뿐만 아니라 대부분의 유형(=, IN, IS NOT, >, START WITH 등)에 적용됩니다.
ex) n.prop = value , n.prop IN list , n.prop IS NOT NULL , n.prop > value , START WITH
✔ POINT 인덱스
◽ 노드 레이블 및 관계 타입과 함께 POINT 인덱스는 포인트 정보를 이용한 경우에 적용됩니다.
ex) n.prop = point({x: value, y: value}) , point.distance(n.prop, center) <= distance
✔ TEXT 인덱스
◽ 노드 레이블 및 관계 타입과 함께 TEXT 인덱스는 문자열 정보를 이용한 경우에 적용됩니다.
◽ 문자열에서만 적용되는 조건자는 항상 TEXT 인덱스로 적용되어 사용됩니다.
ex) n.prop = ‘string’ , n.prop IN [‘encore’, ’en-core’, ’DSC’, ’JeonJonghee’], STARTS WITH, ENDS WITH
지금까지 Neo4j Query Performance에 대한 내용 중 Cypher Query Processing Workflow, Cypher 실행계획, Cypher 질의 시작점을 빠르게 찾을 수 있도록 도와주는 Index에 대해서 알아보았습니다.
Neo4j 쿼리를 잘 사용하기 위해서는 최우선적으로 당연한 Cypher 이해, 인덱스 및 제약조건, 실행계획 확인, 집계 함수 사용, 카타시안 곱 처리 확인 등 다양하게 고려하여 사용되어야 합니다.
관련 정보는 Neo4j Document(https://neo4j.com/docs/cypher-manual/current/query-tuning/) 에서도 확인 할 수 있습니다.
벚꽃도 완연하게 핀 봄이 다가오면서 따뜻하고 화창한 기운이 물씬 풍깁니다.
하지만 아침·저녁으로 일교차 있으므로 건강 챙기시고 여러분의 질문에 답을 찾는 과정이 그래프 데이터베이스를 이해하는 데 많은 도움이 될 것입니다.
감사합니다.
이전글 | 그래프 생성 비교 (Neo4j vs TigerGraph) | 2023-02-22 |
---|