

기계 번역으로 제공되는 번역입니다. 제공된 번역과 원본 영어의 내용이 상충하는 경우에는 영어 버전이 우선합니다.

# Gremlin 쿼리 힌트
<a name="gremlin-query-hints"></a>

쿼리 힌트를 사용하여 Amazon Neptune에서 특정 Gremlin 쿼리에 대한 최적화 및 평가 전략을 지정할 수 있습니다.

쿼리 힌트는 다음 구문을 사용하여 쿼리에 `withSideEffect` 단계를 추가하여 지정합니다.

```
g.withSideEffect(hint, value)
```
+ *힌트* – 적용할 힌트 유형을 식별합니다.
+ *값* – 고려하는 시스템 측면의 동작을 결정합니다.

예를 들어 다음은 Gremlin 순회에 `repeatMode` 힌트를 포함하는 방법을 보여줍니다.

**참고**  
모든 Gremlin 쿼리 힌트 부작용에는 `Neptune#`이라는 접두사가 붙습니다.

```
g.withSideEffect('Neptune#repeatMode', 'DFS').V("3").repeat(out()).times(10).limit(1).path()
```

위의 쿼리는 Neptune 엔진에 기본 Neptune인 *폭 우선*(`BFS`) 대신 *깊이 우선*(`DFS`) 그래프를 순회하도록 지시합니다.

다음 단원에서는 사용 가능한 쿼리 힌트 및 해당 사용법에 대한 추가 정보를 제공합니다.

**Topics**
+ [Gremlin repeatMode 쿼리 힌트](gremlin-query-hints-repeatMode.md)
+ [Gremlin noReordering 쿼리 힌트](gremlin-query-hints-noReordering.md)
+ [Gremlin typePromotion 쿼리 힌트](gremlin-query-hints-typePromotion.md)
+ [Gremlin useDFE 쿼리 힌트](gremlin-query-hints-useDFE.md)
+ [결과 캐시 사용을 위한 Gremlin 쿼리 힌트](gremlin-query-hints-results-cache.md)

# Gremlin repeatMode 쿼리 힌트
<a name="gremlin-query-hints-repeatMode"></a>

Neptune `repeatMode` 쿼리 힌트는 Neptune 엔진이 Gremlin 순회에서 폭 우선, 깊이 우선 또는 청크 깊이 우선으로 `repeat()` 단계를 평가하는 방법을 지정합니다.

`repeat()` 단계의 평가 모드는 단계를 제한된 횟수만큼 반복하는 대신 경로를 검색하거나 따르는 데 사용되는 경우 중요합니다.

## 구문
<a name="gremlin-query-hints-repeatMode-syntax"></a>

`repeatMode` 쿼리 힌트는 쿼리에 `withSideEffect` 단계를 추가하여 지정합니다.

```
g.withSideEffect('Neptune#repeatMode', 'mode').gremlin-traversal
```

**참고**  
모든 Gremlin 쿼리 힌트 부작용에는 `Neptune#`이라는 접두사가 붙습니다.

**사용 가능한 모드**
+ `BFS`

  폭 우선 검색

  `repeat()` 단계의 기본 실행 모드입니다. 이 모드에서는 경로를 따라 더 깊이 들어가기 전에 모든 형제 노드를 가져옵니다.

  이 버전은 메모리 집약적이며 한계가 매우 커질 수 있습니다. 쿼리가 메모리가 부족한 상태에서 실행하여 Neptune 엔진에 의해 취소될 위험이 더 높습니다. 이는 다른 Gremlin 구현과 가장 일치합니다.
+ `DFS`

  깊이 우선 검색

  다음 솔루션으로 이동하기 전에 각 경로를 최대 깊이까지 따릅니다.

  이 경우에는 메모리를 적게 사용합니다. 출발점에서부터 다중 홉(hop)까지 단일 경로를 찾는 것과 같은 상황에서 더 나은 성능을 제공할 수 있습니다.
+ `CHUNKED_DFS`

  청크 깊이 우선 검색

  1 노드(`DFS`) 또는 모든 노드(`BFS)`)가 아닌 1,000개의 노드로 구성된 청크에서 그래프 깊이를 우선 탐구하는 하이브리드 접근 방식입니다.

  Neptune 엔진은 경로를 더 깊이 따라가기 전에 각 수준에서 노드를 최대 1,000개 확보합니다.

  이는 속도와 메모리 사용량 간에 균형 잡힌 접근 방식입니다.

  `BFS`을 사용하려고 하지만 쿼리가 너무 많은 메모리를 사용하는 경우에도 유용합니다.



## 예제
<a name="gremlin-query-hints-repeatMode-example"></a>

다음 단원에서는 Gremlin 순회에 반복 모드가 미치는 영향에 대해 설명합니다.

Neptune에서 `repeat()` 단계의 기본 모드는 모든 순회에 대해 폭 우선(`BFS`) 실행 전략을 수행하는 것입니다.

대부분의 경우 TinkerGraph 구현은 동일한 실행 전략을 사용하지만 경우에 따라 순회 실행을 변경합니다.

예를 들어 TinkerGraph 구현은 다음 쿼리를 수정합니다.

```
g.V("3").repeat(out()).times(10).limit(1).path()
```

이 순회의 `repeat()` 단계는 다음 순회로 '언롤'되어 깊이 우선(`DFS`) 전략이 됩니다.

```
g.V(<id>).out().out().out().out().out().out().out().out().out().out().limit(1).path()
```

**중요**  
Neptune 쿼리 엔진은 이 작업을 자동으로 수행하지 않습니다.

폭 우선(`BFS`)은 기본 실행 전략이며 대부분의 경우 TinkerGraph와 유사합니다. 그러나 깊이 우선(`DFS`) 전략이 더 나은 경우가 있습니다.

 

**BFS(기본값)**  
폭 우선(BFS)은 `repeat()` 연산자의 기본 실행 전략입니다.

```
g.V("3").repeat(out()).times(10).limit(1).path()
```

Neptune 엔진은 10개 홉의 솔루션을 찾기 전에 처음 9개 홉 경계를 완전히 탐색합니다. 이 방법은 최단 경로 쿼리 등 많은 경우에 효과적입니다.

그러나 앞에 나온 예제의 경우 `repeat()` 연산자에 대해 깊이 우선(`DFS`) 모드를 사용하면 순회가 훨씬 빨라집니다.

**DFS**  
다음 쿼리는 `repeat()` 연산자에 깊이 우선(`DFS`) 모드를 사용합니다.

```
g.withSideEffect("Neptune#repeatMode", "DFS").V("3").repeat(out()).times(10).limit(1)
```

이렇게 하면 다음 솔루션을 탐색하기 전에 각 솔루션을 최대 깊이까지 따릅니다.

# Gremlin noReordering 쿼리 힌트
<a name="gremlin-query-hints-noReordering"></a>

Gremlin 순회를 제출할 때 Neptune 쿼리 엔진은 쿼리의 순회 및 재정렬 부분의 구조를 조사하여 평가 및 쿼리 응답 시간에 필요한 작업량을 최소화하려고 합니다. 예를 들어 여러 `has()` 단계와 같이 여러 제약 조건이 있는 순회는 일반적으로 주어진 순서로 평가되지 않지만, 정적 분석을 사용하여 쿼리를 점검한 후에 재정렬됩니다.

Neptune 쿼리 엔진은 어떤 제약 조건이 더 선택적이고 먼저 실행되는지 파악하려고 합니다. 이로 인해 성능이 더 좋아지는 경우가 있지만, Neptune이 쿼리를 평가하도록 선택하는 순서가 항상 최적이 아닐 수도 있습니다.

데이터의 정확한 특성을 알고 있고 쿼리 실행 순서를 수동으로 지정하려는 경우 Neptune `noReordering` 쿼리 힌트를 사용하여 순회가 주어진 순서대로 평가되도록 지정할 수 있습니다.

## 구문
<a name="gremlin-query-hints-noReordering-syntax"></a>

`noReordering` 쿼리 힌트는 쿼리에 `withSideEffect` 단계를 추가하여 지정합니다.

```
g.withSideEffect('Neptune#noReordering', true or false).gremlin-traversal
```

**참고**  
모든 Gremlin 쿼리 힌트 부작용에는 `Neptune#`이라는 접두사가 붙습니다.

**사용 가능한 값**
+ `true`
+ `false`

# Gremlin typePromotion 쿼리 힌트
<a name="gremlin-query-hints-typePromotion"></a>

숫자 값 또는 범위를 필터링하는 Gremlin 순회를 제출할 때 Neptune 쿼리 엔진은 쿼리 실행 시 일반적으로 유형 승격을 사용해야 합니다. 즉, 필터링 대상 값을 포함할 수 있는 모든 유형의 값을 검사해야 합니다.

예를 들어, 55와 같은 값을 필터링하는 경우 엔진은 55와 같은 정수, 55L의 긴 정수, 55.0과 같은 부동 소수점 등을 검색해야 합니다. 각 유형 승격에는 스토리지에 대한 추가 검색이 필요하므로, 겉보기에 간단한 쿼리를 완료하는 데 예상하지 못하게 시간이 오래 걸릴 수 있습니다.

고객 연령 속성이 5보다 큰 모든 버텍스를 검색한다고 가정해 보겠습니다.

```
g.V().has('customerAge', gt(5))
```

순회를 철저하게 실행하려면 Neptune은 쿼리를 확장하여 쿼리하려는 값이 승격될 수 있는 모든 숫자 유형을 검사하도록 해야 합니다. 이 경우 `gt` 필터는 5를 초과하는 정수, 5L 이상의 긴 정수, 5.0을 초과하는 부동 소수점, 5.0을 초과하는 모든 2배수에 적용되어야 합니다. 이러한 각 유형 승격에는 스토리지에 대한 추가 조회가 필요하므로, 이 쿼리에 대해 [Gremlin `profile` API](gremlin-profile-api.md)를 실행하면 숫자 필터당 여러 필터가 표시되며 완료하는 데 예상보다 훨씬 오래 걸립니다.

특정 유형의 값만 찾으면 된다는 사실을 미리 알고 있기 때문에 유형 승격이 불필요한 경우가 많습니다. 이 경우 `typePromotion` 쿼리 힌트를 사용하여 유형 승격을 끄면 쿼리 속도를 크게 높일 수 있습니다.

## 구문
<a name="gremlin-query-hints-typePromotion-syntax"></a>

`typePromotion` 쿼리 힌트는 쿼리에 `withSideEffect` 단계를 추가하여 지정합니다.

```
g.withSideEffect('Neptune#typePromotion', true or false).gremlin-traversal
```

**참고**  
모든 Gremlin 쿼리 힌트 부작용에는 `Neptune#`이라는 접두사가 붙습니다.

**사용 가능한 값**
+ `true`
+ `false`

위 쿼리에 대한 유형 승격을 설정 해제하려면 다음을 사용합니다.

```
g.withSideEffect('Neptune#typePromotion', false).V().has('customerAge', gt(5))
```

# Gremlin useDFE 쿼리 힌트
<a name="gremlin-query-hints-useDFE"></a>

이 쿼리 힌트를 사용하면 DFE를 사용하여 쿼리를 실행할 수 있습니다. 기본적으로 Neptune은 이 쿼리 힌트를 `true`로 설정하지 않으면 DFE를 사용하지 않습니다. 이는 [neptune\$1dfe\$1query\$1engine](parameters.md#parameters-instance-parameters-neptune_dfe_query_engine) 인스턴스 파라미터의 기본값이 `viaQueryHint`로 설정되기 때문입니다. 인스턴스 파라미터를 `enabled`로 설정하면 `useDFE` 쿼리 힌트가 `false`로 설정된 쿼리를 제외한 모든 쿼리에 DFE 엔진이 사용됩니다.

쿼리에 DFE를 활성화하는 예제:

```
g.withSideEffect('Neptune#useDFE', true).V().out()
```

# 결과 캐시 사용을 위한 Gremlin 쿼리 힌트
<a name="gremlin-query-hints-results-cache"></a>

[쿼리 결과 캐시](gremlin-results-cache.md)가 활성화된 경우 다음 쿼리 힌트를 사용할 수 있습니다.

## Gremlin `enableResultCache` 쿼리 힌트
<a name="gremlin-query-hints-results-cache-enableResultCache"></a>

값이 `true`인 `enableResultCache` 쿼리 힌트를 사용하면 쿼리 결과가 이미 캐싱된 경우 캐시에서 쿼리 결과가 반환됩니다. 그렇지 않은 경우 새 결과를 반환하고 캐시에서 지워질 때까지 캐싱합니다. 예제:

```
g.with('Neptune#enableResultCache', true)
 .V().has('genre','drama').in('likes')
```

나중에 정확히 동일한 쿼리를 다시 실행하여 캐싱된 결과에 액세스할 수 있습니다.

이 쿼리 힌트의 값이 `false`이거나 값이 없으면 쿼리 결과가 캐싱되지 않습니다. 하지만 이 값을 `false`로 설정해도 기존의 캐싱된 결과는 지워지지 않습니다. 캐싱된 결과를 지우려면 `invalidateResultCache` 또는 `invalidateResultCachekey` 힌트를 사용하세요.

## Gremlin `enableResultCacheWithTTL` 쿼리 힌트
<a name="gremlin-query-hints-results-cache-enableResultCacheWithTTL"></a>

`enableResultCacheWithTTL` 쿼리 힌트는 캐시에 이미 있는 결과의 TTL에는 영향을 주지 않고 캐싱된 결과가 있는 경우 이를 반환합니다. 현재 캐싱된 결과가 없는 경우 쿼리는 새 결과를 반환하고 `enableResultCacheWithTTL` 쿼리 힌트로 지정된 Time to Live(TTL) 동안 해당 결과를 캐싱합니다. Time to Live는 초 단위로 지정됩니다. 예를 들어, 다음 쿼리는 Time to Live 값을 60초로 지정합니다.

```
g.with('Neptune#enableResultCacheWithTTL', 60)
 .V().has('genre','drama').in('likes')
```

60초의 Time to Live 시간이 끝나기 전에 동일한 쿼리(여기에서는 `g.V().has('genre','drama').in('likes')`)를 `enableResultCache` 또는 `enableResultCacheWithTTL` 쿼리 힌트와 함께 사용하여 캐싱된 결과에 액세스할 수 있습니다.

**참고**  
`enableResultCacheWithTTL`로 지정된 Time to Live 값은 이미 캐싱된 결과에는 영향을 주지 않습니다.  
`enableResultCache`를 사용하여 결과를 이전에 캐싱한 경우, 캐시를 먼저 명시적으로 지워야 `enableResultCacheWithTTL`이 새 결과를 생성하고 지정한 TTL 동안 캐싱합니다.
`enableResultCachewithTTL`를 사용하여 결과를 이전에 캐싱한 경우, 이전 TTL이 먼저 만료되어야 `enableResultCacheWithTTL`이 새 결과를 생성하고 지정한 TTL 동안 캐싱합니다.

Time to Live가 지나면 쿼리의 캐싱된 결과가 지워지고 동일한 쿼리의 후속 인스턴스가 새 결과를 반환합니다. `enableResultCacheWithTTL`가 후속 쿼리에 첨부되면 지정된 TTL을 사용하여 새 결과가 캐싱됩니다.

## Gremlin `invalidateResultCacheKey` 쿼리 힌트
<a name="gremlin-query-hints-results-cache-invalidateResultCacheKey"></a>

`invalidateResultCacheKey` 쿼리 힌트는 `true` 또는 `false` 값을 취할 수 있습니다. `true` 값을 사용하면 `invalidateResultCacheKey`가 연결된 쿼리에 대해 캐싱된 결과가 지워집니다 예를 들어, 다음 예제에서는 쿼리 키 `g.V().has('genre','drama').in('likes')`에 대해 캐싱된 결과가 지워집니다.

```
g.with('Neptune#invalidateResultCacheKey', true)
 .V().has('genre','drama').in('likes')
```

위 예제 쿼리에서는 새 결과가 캐싱되지 않습니다. 기존 캐싱된 결과를 지운 후 새 결과를 캐싱하려는 경우 동일한 쿼리에 `enableResultCache` 또는 `enableResultCacheWithTTL`를 포함할 수 있습니다.

```
g.with('Neptune#enableResultCache', true)
 .with('Neptune#invalidateResultCacheKey', true)
 .V().has('genre','drama').in('likes')
```

## Gremlin `invalidateResultCache` 쿼리 힌트
<a name="gremlin-query-hints-results-cache-invalidateResultCache"></a>

`invalidateResultCache` 쿼리 힌트는 `true` 또는 `false` 값을 취할 수 있습니다. `true` 값을 지정하면 결과 캐시의 모든 결과가 지워집니다. 예제:

```
g.with('Neptune#invalidateResultCache', true)
 .V().has('genre','drama').in('likes')
```

위 예제 쿼리에서는 결과가 캐싱되지 않습니다. 기존 캐시를 완전히 지운 후 새 결과를 캐싱하려는 경우 동일한 쿼리에 `enableResultCache` 또는 `enableResultCacheWithTTL`를 포함할 수 있습니다.

```
g.with('Neptune#enableResultCache', true)
 .with('Neptune#invalidateResultCache', true)
 .V().has('genre','drama').in('likes')
```

## Gremlin `numResultsCached` 쿼리 힌트
<a name="gremlin-query-hints-results-cache-numResultsCached"></a>

`numResultsCached` 쿼리 힌트는 `iterate()`를 포함하는 쿼리에만 사용할 수 있으며, 힌트가 첨부된 쿼리에 대해 캐싱할 최대 결과 수를 지정합니다. `numResultsCached`가 존재할 때 캐싱된 결과는 반환되지 않고 캐싱되기만 한다는 점에 유의하세요.

예를 들어, 다음 쿼리는 결과를 최대 100개까지 캐싱하되 캐싱된 결과는 반환되지 않도록 지정합니다.

```
g.with('Neptune#enableResultCache', true)
 .with('Neptune#numResultsCached', 100)
 .V().has('genre','drama').in('likes').iterate()
```

그런 다음 아래와 같은 쿼리를 사용하여 캐싱된 결과 범위(여기서는 처음 10개)를 검색할 수 있습니다.

```
g.with('Neptune#enableResultCache', true)
 .with('Neptune#numResultsCached', 100)
 .V().has('genre','drama').in('likes').range(0, 10)
```

## Gremlin `noCacheExceptions` 쿼리 힌트
<a name="gremlin-query-hints-results-cache-noCacheExceptions"></a>

`noCacheExceptions` 쿼리 힌트는 `true` 또는 `false` 값을 취할 수 있습니다. `true` 값이 지정되면 결과 캐시와 관련된 모든 예외가 억제됩니다. 예제:

```
g.with('Neptune#enableResultCache', true)
 .with('Neptune#noCacheExceptions', true)
 .V().has('genre','drama').in('likes')
```

특히 이 경우 쿼리 결과가 너무 커서 결과 캐시에 담을 수 없는 상황에서 발생하는 `QueryLimitExceededException`이 표시되지 않습니다.