

本文為英文版的機器翻譯版本，如內容有任何歧義或不一致之處，概以英文版為準。

# Amazon Neptune 中的查詢計劃快取
<a name="access-graph-qpc"></a>

 將查詢提交至 Neptune 時，查詢字串會剖析、最佳化並轉換為查詢計劃，然後由引擎執行。應用程式通常由以不同值執行個體化的常見查詢模式提供支援。查詢計畫快取可以透過快取查詢計畫來減少整體延遲，從而避免剖析和最佳化這類重複模式。

 查詢計畫快取可用於 **OpenCypher** 查詢，包括非參數化或參數化查詢。它針對 READ 和 HTTP 和 Bolt 啟用。OC 變動查詢**不支援**此功能。Gremlin 或 SPARQL 查詢**不支援**此功能。

## 如何強制啟用或停用查詢計劃快取
<a name="access-graph-qpc-enable"></a>

 低延遲參數化查詢預設會啟用查詢計畫快取。只有在延遲低於 **100 毫秒**閾值時，才會快取參數化查詢的計劃。查詢層級查詢提示 可以根據每個查詢 （無論是否參數化） 覆寫此行為`QUERY:PLANCACHE`。它需要與 `USING`子句搭配使用。查詢提示接受 `enabled`或 `disabled`做為值。

------
#### [ AWS CLI ]

強制計劃快取或重複使用：

```
aws neptunedata execute-open-cypher-query \
  --endpoint-url https://{{your-neptune-endpoint}}:{{port}} \
  --open-cypher-query "Using QUERY:PLANCACHE \"enabled\" MATCH(n) RETURN n LIMIT 1"
```

使用參數：

```
aws neptunedata execute-open-cypher-query \
  --endpoint-url https://{{your-neptune-endpoint}}:{{port}} \
  --open-cypher-query "Using QUERY:PLANCACHE \"enabled\" RETURN \$arg" \
  --parameters '{"arg": 123}'
```

強制計劃不會快取或重複使用：

```
aws neptunedata execute-open-cypher-query \
  --endpoint-url https://{{your-neptune-endpoint}}:{{port}} \
  --open-cypher-query "Using QUERY:PLANCACHE \"disabled\" MATCH(n) RETURN n LIMIT 1"
```

如需詳細資訊，請參閱《 AWS CLI 命令參考》中的 [execute-open-cypher-query](https://docs.aws.amazon.com/cli/latest/reference/neptunedata/execute-open-cypher-query.html)。

------
#### [ SDK ]

```
import boto3
from botocore.config import Config

client = boto3.client(
    'neptunedata',
    endpoint_url='https://{{your-neptune-endpoint}}:{{port}}',
    config=Config(read_timeout=None, retries={'total_max_attempts': 1})
)

# Forcing plan to be cached or reused
response = client.execute_open_cypher_query(
    openCypherQuery='Using QUERY:PLANCACHE "enabled" MATCH(n) RETURN n LIMIT 1'
)

print(response['results'])
```

如需其他語言的 AWS SDK 範例，請參閱 [AWS 開發套件](access-graph-opencypher-sdk.md)。

------
#### [ awscurl ]

強制計劃快取或重複使用：

```
awscurl https://{{your-neptune-endpoint}}:{{port}}/openCypher \
  --region {{us-east-1}} \
  --service neptune-db \
  -X POST \
  -d "query=Using QUERY:PLANCACHE \"enabled\" MATCH(n) RETURN n LIMIT 1"
```

**注意**  
此範例假設您的 AWS 登入資料已在您的環境中設定。將 {{us-east-1}} 取代為 Neptune 叢集的區域。

------
#### [ curl ]

強制計劃快取或重複使用：

```
curl https://{{your-neptune-endpoint}}:{{port}}/openCypher \
  -d "query=Using QUERY:PLANCACHE \"enabled\" MATCH(n) RETURN n LIMIT 1"
```

使用參數：

```
curl https://{{your-neptune-endpoint}}:{{port}}/openCypher \
  -d "query=Using QUERY:PLANCACHE \"enabled\" RETURN \$arg" \
  -d "parameters={\"arg\": 123}"
```

強制計劃不會快取或重複使用：

```
curl https://{{your-neptune-endpoint}}:{{port}}/openCypher \
  -d "query=Using QUERY:PLANCACHE \"disabled\" MATCH(n) RETURN n LIMIT 1"
```

------

## 如何判斷計劃是否快取
<a name="access-graph-qpc-status"></a>

 對於 HTTP READ，如果已提交查詢且計劃已快取，則 `explain`會顯示查詢計劃快取的相關詳細資訊。

------
#### [ AWS CLI ]

```
aws neptunedata execute-open-cypher-explain-query \
  --endpoint-url https://{{your-neptune-endpoint}}:{{port}} \
  --open-cypher-query "Using QUERY:PLANCACHE \"enabled\" MATCH(n) RETURN n LIMIT 1" \
  --explain-mode details
```

如需詳細資訊，請參閱《 AWS CLI 命令參考》中的 [execute-open-cypher-explain-query](https://docs.aws.amazon.com/cli/latest/reference/neptunedata/execute-open-cypher-explain-query.html)。

------
#### [ SDK ]

```
import boto3
from botocore.config import Config

client = boto3.client(
    'neptunedata',
    endpoint_url='https://{{your-neptune-endpoint}}:{{port}}',
    config=Config(read_timeout=None, retries={'total_max_attempts': 1})
)

response = client.execute_open_cypher_explain_query(
    openCypherQuery='Using QUERY:PLANCACHE "enabled" MATCH(n) RETURN n LIMIT 1',
    explainMode='details'
)

print(response['results'].read().decode('utf-8'))
```

如需其他語言的 AWS SDK 範例，請參閱 [AWS 開發套件](access-graph-opencypher-sdk.md)。

------
#### [ awscurl ]

```
awscurl https://{{your-neptune-endpoint}}:{{port}}/openCypher \
  --region {{us-east-1}} \
  --service neptune-db \
  -X POST \
  -d "query=Using QUERY:PLANCACHE \"enabled\" MATCH(n) RETURN n LIMIT 1" \
  -d "explain=details"
```

**注意**  
此範例假設您的 AWS 登入資料已在您的環境中設定。將 {{us-east-1}} 取代為 Neptune 叢集的區域。

------
#### [ curl ]

```
curl https://{{your-neptune-endpoint}}:{{port}}/openCypher \
  -d "query=Using QUERY:PLANCACHE \"enabled\" MATCH(n) RETURN n LIMIT 1" \
  -d "explain=details"
```

------

如果計劃已快取，`explain`輸出會顯示：

```
Query: <QUERY STRING>
Plan cached by request: <REQUEST ID OF FIRST TIME EXECUTION>
Plan cached at: <TIMESTAMP OF FIRST TIME EXECUTION>
Parameters: <PARAMETERS, IF QUERY IS PARAMETERIZED QUERY>
Plan cache hits: <NUMBER OF CACHE HITS FOR CACHED PLAN>
First query evaluation time: <LATENCY OF FIRST TIME EXECUTION>

The query has been executed based on a cached query plan. Detailed explain with operator runtime statistics can be obtained by running the query with plan cache disabled (using HTTP parameter planCache=disabled).
```

 使用 Bolt 時，不支援解釋功能。

## 移出
<a name="access-graph-qpc-eviction"></a>

 快取存留時間 (TTL) 或已達到快取查詢計劃的最大數量時，會移出查詢計劃。當查詢計畫命中時，TTL 會重新整理。預設值為：
+  1000 - 每個執行個體可快取的計劃數量上限。
+  TTL - 300，000 毫秒或 5 分鐘。快取命中會重新啟動 TTL，並將其重設回 5 分鐘。

## 導致計劃無法快取的條件
<a name="access-graph-qpc-conditions"></a>

 在下列情況下，不會使用查詢計劃快取：

1.  使用查詢提示 提交查詢時`QUERY:PLANCACHE "disabled"`。您可以重新執行查詢並移除 `QUERY:PLANCACHE "disabled"`，以啟用查詢計劃快取。

1.  如果提交的查詢不是參數化查詢，且不包含提示 `QUERY:PLANCACHE "enabled"`。

1.  如果查詢評估時間大於延遲閾值，則不會快取查詢，且會被視為長時間執行的查詢，而不會受益於查詢計劃快取。

1.  如果查詢包含未傳回任何結果的模式。
   +  例如，當具有指定標籤的節點為零`MATCH (n:nonexistentLabel) return n`時。
   +  例如，當包含 的節點為零`parameters={"param": "abcde"}`時`MATCH (n {name: $param}) return n`，使用 `name=abcde`。

1.  如果查詢參數是複合類型，例如 `list`或 `map`。

   ```
   curl https://{{your-neptune-endpoint}}:{{port}}/openCypher \
     -d "query=Using QUERY:PLANCACHE \"enabled\" RETURN \$arg" \
     -d "parameters={\"arg\": [1, 2, 3]}"
   
   curl https://{{your-neptune-endpoint}}:{{port}}/openCypher \
     -d "query=Using QUERY:PLANCACHE \"enabled\" RETURN \$arg" \
     -d "parameters={\"arg\": {\"a\": 1}}"
   ```

1.  如果查詢參數是尚未成為資料載入或資料插入操作一部分的字串。例如，如果 `CREATE (n {name: "X"})` 執行以插入 `"X"`，則 `RETURN "X"` 會快取，而 `RETURN "Y"`不會快取，因為 `"Y"` 尚未插入，並且不存在於資料庫中。