그래프 쿼리 권장사항
이 문서에서는 BigQuery 그래프 쿼리를 최적화하기 위한 권장사항을 설명합니다.
카디널리티가 낮은 노드에서 경로 순회 시작
중간 결과 집합을 작게 유지하고 쿼리 실행 속도를 높이려면 경로 순회 방향과 관계없이 경로 순회가 카디널리티가 낮은 노드에서 시작되도록 그래프 쿼리를 작성합니다. 다음 MATCH 문은 모든 일치 항목을 계산한 후 필터링하는 대신 속성 필터를 사용하여 가능한 시작 노드 수를 줄입니다.
MATCH (p:Person {id: 10})-[own:Owns]->(a:Account)
MATCH (a:Account WHERE balance > 10)<-[own:Owns]-(p:Person)
이는 수량화된 경로 쿼리에 특히 중요합니다.
MATCH (p:Person {id: 10})-[own:Owns]->{1,3}(a:Account)
연결 확인에 ANY 또는 ANY SHORTEST 문법 사용
수량화된 경로 쿼리는 소스 노드와 대상 노드 간에 중복 경로를 반환할 수 있습니다. 연결을 확인하는 것이 목표이고 가능한 모든 경로가 필요하지 않은 경우 ANY 또는 ANY SHORTEST를 사용하여 중복 계산을 줄이고 경로 조회 효율성을 개선합니다. 예를 들어 다음 MATCH 문은 ANY SHORTEST를 사용하여 각 노드 쌍 간에 경로를 하나만 유지합니다.
MATCH ANY SHORTEST (a1:Account)-[t:Transfers]->{1,3}(a2:Account)
방향 경로 순회 사용
BigQuery 그래프 스키마는 방향이 지정됩니다. 즉, 각 에지에는 소스 노드와 대상 노드가 있습니다. 그래프 쿼리
문법은 모든 방향으로 경로 순회를 허용하지만 (예: -[edge]-) 성능 향상을 위해 방향 경로 순회 (예: -[edge]-> 또는
<-[edge]-)를 사용하는 것이 좋습니다. 모든 방향 경로 순회는 성능 저하를 일으킬 수 있습니다.
다음 MATCH 문은 모든 방향 경로 순회를 사용합니다.
-- Avoid.
MATCH (a1:Account {id: 7})-[t:Transfers]-(a2:Account)
대신 UNION ALL을 사용하여 두 방향 순회를 결합합니다.
MATCH (a1:Account {id: 7})-[t:Transfers]->(a2:Account)
...
UNION ALL
...
MATCH (a1:Account {id: 7})<-[t:Transfers]-(a2:Account)
라벨 명시적으로 지정
쿼리에서 노드 또는 에지 라벨이 생략되면 BigQuery 그래프는 적격한 모든 노드 및 에지 라벨을 열거합니다. 이 열거로 인해 필요 이상으로 많은 라벨이 검사될 수 있습니다. 이를 방지하려면 가능한 경우 쿼리의 모든 노드와 에지에 라벨을 지정하세요.
예를 들어 다음 쿼리는 Account 및 Transfers 라벨을 지정합니다.
GRAPH graph_db.FinGraph
MATCH (a1:Account)-[t:Transfers]->(a2:Account)
RETURN COUNT(*) AS num_transfers;
노드 간에 다른 불필요한 관계를 검사할 수 있으므로 라벨을 생략하지 마세요. 다음 쿼리에서 a1은 계정 또는
개인을 나타낼 수 있으며 t은 이체 또는 계정 소유권을 나타낼 수 있습니다.
GRAPH graph_db.FinGraph
MATCH (a1)-[t]->(a2)
RETURN COUNT(*) AS num_transfers;
단일 MATCH 문 선호
BigQuery 그래프를 사용하면 단일 그래프 쿼리에 여러 MATCH 문을 포함할 수 있습니다. 이러한 문은 동일한 노드 또는 에지를 나타내는 다중 선언된 변수로 연결됩니다. 그러나 여러 MATCH 문을 사용하면 문 간에 카디널리티 이점이 줄어들 수 있습니다. 가능하면 성능 향상을 위해 단일 MATCH 문을 사용하세요.
예를 들어 다음 쿼리는 동일하지만 첫 번째 쿼리는 단일 MATCH 문을 사용하므로 더 나은 성능을 제공합니다.
-- Preferred syntax.
GRAPH graph_db.FinGraph
MATCH
(p:Person {id: 1})-[o:Owns]->
(a:Account)-[t:Transfers]->(a2:Account)
RETURN o.account_id, t.amount;
-- Avoid this syntax.
GRAPH graph_db.FinGraph
MATCH (p:Person {id: 1})-[o:Owns]->(a:Account)
MATCH (a:Account)-[t:Transfers]->(a2:Account)
RETURN o.account_id, t.amount;
카디널리티가 높은 노드에서 순회된 에지 제한
그래프를 쿼리할 때 일부 노드에는 다른 노드에 비해 들어오거나 나가는 에지 수가 훨씬 많을 수 있습니다. 이러한 카디널리티가 높은 노드를 슈퍼 노드 또는 허브 노드 라고도 합니다. 슈퍼 노드를 통과하는 순회는 많은 양의 데이터 처리와 관련될 수 있으므로 슈퍼 노드로 인해 성능 문제가 발생할 수 있으며 이로 인해 데이터 왜도가 발생하고 실행 시간이 길어질 수 있습니다.
슈퍼 노드가 있는 그래프의 쿼리를 최적화하려면
ROW_NUMBER() 함수
를 FILTER 절 또는 WHERE 절 내에서 사용하여 쿼리가 노드에서 순회하는 에지 수를 제한합니다.MATCH 이 기법은 슈퍼 노드에서 모든 연결을 완전하게 열거할 필요가 없는 경우에 특히 유용합니다.
예를 들어 FinGraph의 일부 계정에 트랜잭션 수가 많은 경우 ROW_NUMBER()를 사용하여 각 Account에 대해 고려할 Transfers 에지 수를 제한하고 비효율적인 쿼리를 방지할 수 있습니다.
GRAPH graph_db.FinGraph
MATCH (a1:Account)-[e1:Transfers WHERE e1 IN {
GRAPH graph_db.FinGraph
-- Sample 5 edges per source node
MATCH -[selected_e:Transfers]->
FILTER ROW_NUMBER() OVER (
PARTITION BY SOURCE_NODE_ID(selected_e)) < 5
RETURN selected_e
}]->{1,3}(a2:Account)
RETURN COUNT(*) AS cnt;
멀티 홉 쿼리에서 중간 노드 또는 에지 샘플링
ROW_NUMBER()를 사용하여 멀티 홉 쿼리에서 중간 노드를 샘플링해 쿼리 효율성을 향상시킬 수도 있습니다. 이 기법은 쿼리가 각 중간 노드에 대해 고려하는 경로 수를 제한하여 효율성을 개선합니다. 이렇게 하려면 멀티 홉 쿼리를 NEXT로 구분된 MATCH 문 여러 개로 나누고 샘플링해야 하는 중간 지점에 ROW_NUMBER()를 적용합니다.
GRAPH graph_db.FinGraph
MATCH (a1:Account)-[e1:Transfers]->(a2:Account)
-- Sample 5 destination nodes per a1 source node
FILTER ROW_NUMBER() OVER (PARTITION BY ELEMENT_ID(a1)) < 5
RETURN a1, a2
NEXT
MATCH (a2)-[e2:Transfers]->(a3:Account)
RETURN a1.id AS src_id, a2.id AS mid_id, a3.id AS dst_id;
다음 단계
- 그래프 쿼리 작성에 대한 자세한 내용은 쿼리 개요를 참조하세요.
- 스키마 권장사항에 대해 자세히 알아보기 .