

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

# 在 Amazon Keyspaces 中使用 CQL 查詢
<a name="working-with-queries"></a>

本節介紹如何在 Amazon Keyspaces （適用於 Apache Cassandra) 中使用查詢。可用於查詢、轉換和管理資料的 CQL 陳述式為 `SELECT`、`UPDATE`、 `INSERT`和 `DELETE`。下列主題概述使用查詢時一些較複雜的可用選項。如需範例的完整語言語法，請參閱 [Amazon Keyspaces 中的 DML 陳述式 （資料處理語言）](cql.dml.md)。

**Topics**
+ [在 Amazon Keyspaces 的查詢中使用 `IN`運算子搭配 `SELECT`陳述式](in.select.md)
+ [在 Amazon Keyspaces 中使用批次陳述式](batchStatements.md)
+ [在 Amazon Keyspaces `ORDER BY`中使用 排序結果](ordering-results.md)
+ [在 Amazon Keyspaces 中分頁結果](paginating-results.md)

# 在 Amazon Keyspaces 的查詢中使用 `IN`運算子搭配 `SELECT`陳述式
<a name="in.select"></a>

**SELECT IN**

您可以使用 `SELECT`陳述式從資料表查詢資料，該陳述式會讀取資料表中一或多個資料列的一或多個資料欄，並傳回結果集，其中包含符合請求的資料列。`SELECT` 陳述式包含 `select_clause`，可決定要讀取哪些資料欄，以及在結果集中傳回哪些資料欄。子句可以包含在傳回資料之前轉換資料的指示。選用`WHERE`的 子句指定哪些資料列必須查詢，並由屬於主索引鍵之資料欄上的關係組成。Amazon Keyspaces 支援 `WHERE`子句中的 `IN` 關鍵字。本節使用範例來示範 Amazon Keyspaces 如何使用 `IN`關鍵字處理`SELECT`陳述式。

此範例示範 Amazon Keyspaces 如何將具有 `IN`關鍵字的`SELECT`陳述式分解為*子查詢*。在此範例中，我們使用名為 的資料表`my_keyspace.customers`。資料表有一個主索引鍵資料欄 `department_id`、兩個叢集資料欄 `sales_region_id` 和 `sales_representative_id`，以及一個包含資料欄中客戶名稱的資料`customer_name`欄。

```
SELECT * FROM my_keyspace.customers;

         department_id | sales_region_id | sales_representative_id | customer_name
        ---------------+-----------------+-------------------------+--------------
          0            |        0        |            0            |    a
          0            |        0        |            1            |    b
          0            |        1        |            0            |    c
          0            |        1        |            1            |    d
          1            |        0        |            0            |    e
          1            |        0        |            1            |    f
          1            |        1        |            0            |    g
          1            |        1        |            1            |    h
```

使用此資料表，您可以執行下列`SELECT`陳述式，使用 `WHERE`子句中的`IN`關鍵字來尋找您感興趣的部門和銷售區域中的客戶。下列陳述式是此範例。

```
SELECT * FROM my_keyspace.customers WHERE department_id IN (0, 1) AND sales_region_id IN (0, 1);
```

Amazon Keyspaces 將此陳述式分成四個子查詢，如下列輸出所示。

```
SELECT * FROM my_keyspace.customers WHERE department_id = 0 AND sales_region_id = 0;

 department_id | sales_region_id | sales_representative_id | customer_name
---------------+-----------------+-------------------------+--------------
  0            |        0        |           0             |    a
  0            |        0        |           1             |    b

SELECT * FROM my_keyspace.customers WHERE department_id = 0 AND sales_region_id = 1;

 department_id | sales_region_id | sales_representative_id | customer_name
---------------+-----------------+-------------------------+--------------
  0            |        1        |          0              |    c
  0            |        1        |          1              |    d

SELECT * FROM my_keyspace.customers WHERE department_id = 1 AND sales_region_id = 0;

 department_id | sales_region_id | sales_representative_id | customer_name
---------------+-----------------+-------------------------+--------------
  1            |        0        |          0              |    e
  1            |        0        |          1              |    f

SELECT * FROM my_keyspace.customers WHERE department_id = 1 AND sales_region_id = 1;

 department_id | sales_region_id | sales_representative_id | customer_name
---------------+-----------------+-------------------------+--------------
  1            |        1        |           0             |    g
  1            |        1        |           1             |    h
```

使用`IN`關鍵字時，Amazon Keyspaces 會在下列任何情況下自動分頁結果：
+ 每處理第 10 個子查詢之後。
+ 處理 1MB 的邏輯 IO 之後。
+ 如果您已設定 `PAGE SIZE`，Amazon Keyspaces 會在讀取查詢數目後分頁，以根據集合 進行處理`PAGE SIZE`。
+ 當您使用 `LIMIT`關鍵字來減少傳回的資料列數時，Amazon Keyspaces 會在根據集合 讀取要處理的查詢數之後進行分頁`LIMIT`。

 下表用於說明 範例。

如需分頁的詳細資訊，請參閱 [在 Amazon Keyspaces 中分頁結果](paginating-results.md)。

```
SELECT * FROM my_keyspace.customers;

         department_id | sales_region_id | sales_representative_id | customer_name
        ---------------+-----------------+-------------------------+--------------
          2            |        0        |          0              |    g
          2            |        1        |          1              |    h
          2            |        2        |          2              |    i
          0            |        0        |          0              |    a
          0            |        1        |          1              |    b
          0            |        2        |          2              |    c
          1            |        0        |          0              |    d
          1            |        1        |          1              |    e
          1            |        2        |          2              |    f
          3            |        0        |          0              |    j
          3            |        1        |          1              |    k
          3            |        2        |          2              |    l
```

您可以在此表格上執行下列陳述式，以查看分頁的運作方式。

```
SELECT * FROM my_keyspace.customers WHERE department_id IN (0, 1, 2, 3) AND sales_region_id IN (0, 1, 2) AND sales_representative_id IN (0, 1);
```

Amazon Keyspaces 將此陳述式處理為 24 個子查詢，因為此查詢中包含之所有`IN`詞彙的笛卡兒產品基數為 24。

```
 department_id | sales_region_id | sales_representative_id | customer_name
---------------+-----------------+-------------------------+--------------
  0            |        0        |          0              |    a
  0            |        1        |          1              |    b
  1            |        0        |          0              |    d
  1            |        1        |          1              |    e

---MORE---
 department_id | sales_region_id | sales_representative_id | customer_name
---------------+-----------------+-------------------------+--------------
  2            |        0        |          0              |    g
  2            |        1        |          1              |    h
  3            |        0        |          0              |    j

---MORE---
 department_id | sales_region_id | sales_representative_id | customer_name
---------------+-----------------+-------------------------+--------------
  3            |        1        |          1              |    k
```

此範例示範如何在具有 `IN`關鍵字的`SELECT`陳述式中使用 `ORDER BY`子句。

```
SELECT * FROM my_keyspace.customers WHERE department_id IN (3, 2, 1) ORDER BY sales_region_id DESC;
        
         department_id | sales_region_id | sales_representative_id | customer_name
        ---------------+-----------------+-------------------------+--------------
          3            |        2        |          2              |    l
          3            |        1        |          1              |    k
          3            |        0        |          0              |    j
          2            |        2        |          2              |    i
          2            |        1        |          1              |    h
          2            |        0        |          0              |    g
          1            |        2        |          2              |    f
          1            |        1        |          1              |    e
          1            |        0        |          0              |    d
```

子查詢的處理順序是分割區索引鍵和叢集索引鍵資料欄在查詢中呈現的順序。在下列範例中，會先處理分割區索引鍵值 ”2” 的子查詢，接著處理分割區索引鍵值 ”3” 和 ”1” 的子查詢。如果存在，則會根據查詢的排序子句或資料表建立期間定義的資料表叢集順序，來排序指定子查詢的結果。

```
SELECT * FROM my_keyspace.customers WHERE department_id IN (2, 3, 1) ORDER BY sales_region_id DESC;

         department_id | sales_region_id | sales_representative_id | customer_name
        ---------------+-----------------+-------------------------+--------------
          2            |        2        |          2              |    i
          2            |        1        |          1              |    h
          2            |        0        |          0              |    g
          3            |        2        |          2              |    l
          3            |        1        |          1              |    k
          3            |        0        |          0              |    j
          1            |        2        |          2              |    f
          1            |        1        |          1              |    e
          1            |        0        |          0              |    d
```

# 在 Amazon Keyspaces 中使用批次陳述式
<a name="batchStatements"></a>

您可以將多個 `INSERT`、 `UPDATE`和 `DELETE`操作合併為`BATCH`陳述式。`LOGGED`批次為預設值。

```
batch_statement ::=     BEGIN [ UNLOGGED ] BATCH
                        [ USING update_parameter( AND update_parameter)* ]
                        modification_statement ( ';' modification_statement )*
                        APPLY BATCH
modification_statement ::= insert_statement | update_statement | delete_statement
```

當您執行批次陳述式時，驅動程式會將批次中的所有陳述式合併為單一批次操作。

若要決定要使用的批次操作類型，您可以考慮下列準則。

在下列情況下使用記錄的批次：  
+ 您需要原子交易保證。
+ 稍微較高的延遲是可接受的取捨。

在下列情況下使用未記錄的批次：  
+ 您需要最佳化單一分割區操作。
+ 您想要減少網路額外負荷。
+ 您有高輸送量需求。

如需批次陳述式配額的詳細資訊，請參閱 [Amazon Keyspaces 配額 （適用於 Apache Cassandra)](quotas.md)。

## 未記錄的批次
<a name="batchStatements-unlogged"></a>

使用**未記錄的批次**時，Amazon Keyspaces 會將多個操作視為單一請求來處理，而無需維護批次日誌。透過未記錄的批次操作，有些動作可能會成功，有些則失敗。當您想要：
+ 最佳化單一分割區中的操作。
+ 透過將相關請求分組來減少網路流量。

未記錄批次的語法類似於已記錄批次的語法，並新增 `UNLOGGED`關鍵字。

```
BEGIN UNLOGGED BATCH
    INSERT INTO users (id, firstname, lastname) VALUES (1, 'John', 'Doe');
    INSERT INTO users (id, firstname, lastname) VALUES (2, 'Jane', 'Smith');
APPLY BATCH;
```

## 已記錄的批次
<a name="batchStatements-logged"></a>

**記錄**的批次會將多個寫入動作合併為單一原子操作。當您執行記錄的批次時：
+ 所有動作會一起成功或一起失敗。
+ 操作是同步且等冪的。
+ 您可以寫入多個 Amazon Keyspaces 資料表，只要它們位於相同的 AWS 帳戶和 AWS 區域。

記錄的批次可能會有稍微較高的延遲。對於高輸送量應用程式，請考慮使用未記錄的批次。

在 Amazon Keyspaces 中使用記錄批次無需額外費用。您只需為屬於批次操作的寫入付費。Amazon Keyspaces 會執行批次中每一列的兩個基礎寫入：一個用於準備批次的資料列，另一個用於遞交批次。為使用記錄批次的資料表規劃容量時，請記住，批次中的每一列都需要標準寫入操作的兩倍容量。例如，如果您的應用程式每秒執行一個記錄批次，其中包含三個 1KB 資料列，則您需要佈建六個寫入容量單位 (WCUs)，而個別寫入或未記錄批次只需要三個 WCUs。

如需定價的相關資訊，請參閱 [Amazon Keyspaces （適用於 Apache Cassandra) 定價](https://aws.amazon.com/keyspaces/pricing)。

### 批次操作的最佳實務
<a name="batchStatements-best-practice"></a>

使用 Amazon Keyspaces 批次操作時，請考慮下列建議實務。
+ 啟用自動擴展，讓您的資料表有足夠的輸送量容量來處理批次操作，以及記錄批次的額外輸送量需求。
+ 當操作可以獨立執行時，請使用個別操作或未記錄的批次，而不會影響應用程式的正確性。
+ 設計您的應用程式，將相同資料列的並行更新降至最低，因為同時批次操作可能會衝突和失敗。
+ 對於沒有原子需求的高輸送量大量資料擷取，請使用個別寫入操作或未記錄的批次。

### 一致性和並行
<a name="batchStatements-consistency"></a>

Amazon Keyspaces 會針對記錄的批次強制執行下列一致性和並行規則：
+ 所有批次操作都使用`LOCAL_QUORUM`一致性層級。
+ 影響不同資料列的並行批次可以同時執行。
+ 持續批次中涉及之資料列的並行 `INSERT``UPDATE`、 或 `DELETE`操作會失敗並產生衝突。

### 支援的運算子和條件
<a name="batchStatements-operators"></a>

支援的`WHERE`子句運算子：  
+ 等式 (=)

不支援的運算子：  
+ 範圍運算子 (＞、＜、>=、<=)
+ `IN`運算子
+ `LIKE`運算子
+ `BETWEEN`運算子

記錄的批次中不支援：  
+ 影響相同資料列的多個陳述式
+ 計數器操作
+ 範圍刪除

### 已記錄批次陳述式的失敗條件
<a name="batchStatement-failures"></a>

在下列任何情況下，記錄的批次操作可能會失敗：
+ 條件表達式 （例如 `IF NOT EXISTS`或 `IF`) 會評估為 false。
+ 一或多個操作包含無效的參數。
+ 請求與在相同資料列上執行的另一個批次操作衝突。
+ 資料表缺少足夠的佈建容量。
+ 資料列超過大小上限。
+ 輸入資料格式無效。

### 批次陳述式和多區域複寫
<a name="batchStatements-multiregion"></a>

在多區域部署中：
+ 來源區域操作是同步和原子的。
+ 目的地區域操作是非同步的。
+ 所有批次操作都會複寫到目的地區域，但可能無法在應用程式期間維持隔離。

### 監控批次操作
<a name="batchStatements-monitoring"></a>

您可以使用 Amazon CloudWatch 指標監控批次操作，以追蹤效能、錯誤和用量模式。Amazon Keyspaces 提供下列 CloudWatch 指標，用於監控每個資料表的批次操作：
+ `SuccessfulRequestCount` – 追蹤成功的批次操作。
+ `Latency` – 測量批次操作效能。
+ `ConsumedWriteCapacityUnits` – 監控批次操作的容量耗用。

如需詳細資訊，請參閱[Amazon Keyspaces 指標](metrics-dimensions.md#keyspaces-metrics-dimensions)。

除了 CloudWatch 指標之外，您還可以使用 AWS CloudTrail 記錄所有 Amazon Keyspaces API 動作。批次中的每個 API 動作都會記錄在 CloudTrail 中，讓您更輕鬆地追蹤和稽核 Amazon Keyspaces 資料表中的批次操作。

### 批次操作範例
<a name="batchStatements-examples"></a>

以下是基本記錄批次陳述式的範例。

```
BEGIN BATCH
    INSERT INTO users (id, firstname, lastname) VALUES (1, 'John', 'Doe');
    INSERT INTO users (id, firstname, lastname) VALUES (2, 'Jane', 'Smith');
APPLY BATCH;
```

這是包含 `INSERT`、 `UPDATE`和 `DELETE`陳述式的批次範例。

```
BEGIN BATCH
    INSERT INTO users (id, firstname, lastname) VALUES (1, 'John', 'Doe');
    UPDATE users SET firstname = 'Johnny' WHERE id = 2;
    DELETE FROM users WHERE id = 3;
APPLY BATCH;
```

這是使用用戶端時間戳記的批次範例。

```
BEGIN BATCH
    INSERT INTO users (id, firstname, lastname) VALUES (1, 'John', 'Stiles') USING TIMESTAMP 1669069624;
    INSERT INTO users (id, firstname, lastname) VALUES (2, 'Jane', 'Doe') USING TIMESTAMP 1669069624;
APPLY BATCH;

BEGIN BATCH
    UPDATE users USING TIMESTAMP 1669069624 SET firstname = 'Carlos' WHERE id = 1;
    UPDATE users USING TIMESTAMP 1669069624 SET firstname = 'Diego' WHERE id = 2;
APPLY BATCH;
```

這是條件式批次的範例。

```
BEGIN BATCH
    INSERT INTO users (id, firstname, lastname) VALUES (1, 'Jane', 'Doe') IF NOT EXISTS;
    INSERT INTO users (id, firstname, lastname) VALUES (2, 'John', 'Doe') IF NOT EXISTS;
APPLY BATCH;


BEGIN BATCH
    UPDATE users SET lastname = 'Stiles' WHERE id = 1 IF lastname = 'Doe';
    UPDATE users SET lastname = 'Stiles' WHERE id = 2 IF lastname = 'Doe';
APPLY BATCH;
```

這是使用存留時間 (TTL) 的批次範例。

```
BEGIN BATCH
    INSERT INTO users (id, firstname, lastname) VALUES (1, 'John', 'Doe') USING TTL 3600;
    INSERT INTO users (id, firstname, lastname) VALUES (2, 'Jane', 'Smith') USING TTL 7200;
APPLY BATCH;
```

這是更新多個資料表的批次陳述式範例。

```
BEGIN BATCH
    INSERT INTO users (id, firstname) VALUES (1, 'John');
    INSERT INTO user_emails (user_id, email) VALUES (1, 'john@example.com');
APPLY BATCH;
```

這是使用使用者定義類型 (UDTs) 的批次操作範例。此範例假設 UDT `address`存在。

```
BEGIN BATCH
    INSERT INTO users (id, firstname, address)
    VALUES (1, 'John', {street: '123 Main St', city: 'NYC', zip: '10001'});
    INSERT INTO users (id, firstname, address)
    VALUES (2, 'Jane', {street: '456 Oak Ave', city: 'LA', zip: '90210'});
APPLY BATCH;

BEGIN BATCH
    UPDATE users SET address.zip = '10002' WHERE id = 1;
    UPDATE users SET address.city = 'Boston' WHERE id = 2;
APPLY BATCH;
```

# 在 Amazon Keyspaces `ORDER BY`中使用 排序結果
<a name="ordering-results"></a>

`ORDER BY` 子句指定`SELECT`陳述式中傳回之結果的排序順序。陳述式會以引數的形式取得資料欄名稱清單，而且您可以為每個資料欄指定資料的排序順序。您只能依子句的順序指定叢集資料欄，不允許非叢集資料欄。

傳回結果的兩個可用排序順序選項`ASC`適用於遞增和`DESC`遞減排序順序。

```
SELECT * FROM my_keyspace.my_table ORDER BY (col1 ASC, col2 DESC, col3 ASC);

         col1 | col2 | col3  
        ------+------+------
          0   |  6   |  a   
          1   |  5   |  b   
          2   |  4   |  c   
          3   |  3   |  d   
          4   |  2   |  e   
          5   |  1   |  f   
          6   |  0   |  g
```

```
SELECT * FROM my_keyspace.my_table ORDER BY (col1 DESC, col2 ASC, col3 DESC);

         col1 | col2 | col3  
        ------+------+------
          6   |  0   |  g   
          5   |  1   |  f   
          4   |  2   |  e   
          3   |  3   |  d   
          2   |  4   |  c   
          1   |  5   |  b   
          0   |  6   |  a
```

如果您未在查詢陳述式中指定排序順序，則會使用叢集資料欄的預設排序。

您可以在排序子句中使用的可能排序順序取決於資料表建立時指派給每個叢集欄的排序順序。查詢結果只能依照資料表建立時為所有叢集資料欄定義的順序，或反向定義的排序順序進行排序。不允許其他可能的組合。

例如，如果資料表的 `CLUSTERING ORDER`是 (col1 ASC、col2 DESC、col3 ASC)，則 的有效參數`ORDER BY`是 (col1 ASC、col2 DESC、col3 ASC) 或 (col1 DESC、col2 ASC、col3 DESC)。如需 的詳細資訊`CLUSTERING ORDER`，請參閱 `table_options`下的 [CREATE TABLE](cql.ddl.table.md#cql.ddl.table.create)。

# 在 Amazon Keyspaces 中分頁結果
<a name="paginating-results"></a>

當資料讀取處理`SELECT`陳述式超過 1 *MB 時，Amazon Keyspaces 會自動從陳述式分頁*結果。 `SELECT`使用分頁時，`SELECT`陳述式結果會分為大小為 1 MB （或更少） 的「頁面」資料。應用程式可以處理結果的第一頁、第二頁，以此類推。用戶端在處理傳回多列的`SELECT`查詢時，應一律檢查分頁字符。

 如果用戶端提供的 `PAGE SIZE`需要讀取超過 1 MB 的資料，Amazon Keyspaces 會根據 1 MB 的資料讀取增量自動將結果分成多個頁面。

例如，如果資料列的平均大小為 100 KB，而您指定的 `PAGE SIZE`為 20，Amazon Keyspaces 會在讀取 10 列 (1000 KB 的資料讀取） 之後自動分頁資料。

由於 Amazon Keyspaces 會根據讀取處理請求的資料列數來分頁結果，而不是結果集中傳回的資料列數，因此如果您執行篩選的查詢，某些頁面可能不包含任何資料列。

例如，如果您將 `PAGE SIZE`設定為 10，且 Keyspaces 評估 30 列來處理`SELECT`查詢，Amazon Keyspaces 將傳回三個頁面。如果只有一部分的資料列符合您的查詢，有些頁面可能少於 10 個資料列。如需`LIMIT`查詢 `PAGE SIZE` 如何影響讀取容量的範例，請參閱 [預估限制查詢的讀取容量耗用量](limit_queries.md)。

如需 Apache Cassandra 分頁的比較，請參閱 [分頁](functional-differences.md#functional-differences.paging)。