

本文属于机器翻译版本。若本译文内容与英语原文存在差异，则一律以英文原文为准。

# OpenSearch 结构化查询语言 (SQL)
<a name="CWL_AnalyzeLogData_SQL"></a>

本节包含使用 OpenSearch SQL 查询 CloudWatch 日志的基本介绍。如果您习惯使用关系数据库，则它可提供熟悉的选项。 OpenSearch SQL 提供了 SQL 功能的子集，使其成为执行临时查询和数据分析任务的理想选择。在 S OpenSearch QL 中，您可以使用诸如 SELECT、FROM、WHERE、GROUP BY、HAVING 等命令和各种其他 SQL 命令和函数。您可以 JOINs 跨日志组执行，使用子查询关联日志组中的数据，并使用丰富的 JSON、数学、字符串、条件和其他 SQL 函数集对日志和安全数据进行强有力的分析。

使用 `filterIndex` 可以强制查询仅扫描在查询中指定的字段上编制索引的日志组，从而返回已编制索引的数据 跳过没有任何包含查询中指定字段的日志事件的日志组，而只扫描与该字段索引查询中指定的值相匹配的日志组，从而减少扫描量。`filterIndex`用于指定字段名称以及字段名称和值，以便仅查询包含指定字段和值的索引数据。

您可以使用 OpenSearch SQL 查询标准日志类中的日志组。SQL 还支持使用数据源名称和数据源类型进行查询。

**注意**  
下表列出了 CloudWatch 日志中支持的 SQL 命令和函数。有关包括语法在内的所有 OpenSearch SQL 命令的信息，请参阅《 OpenSearch 服务开发人员指南》中[支持的 SQL 命令](https://docs.aws.amazon.com/opensearch-service/latest/developerguide/supported-directquery-sql.html)。  
有关您可以使用的其他查询语言的信息，请参阅 L [CloudWatch ogs Insights](https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/CWL_QuerySyntax.html)、Ser [OpenSearch vice PPL](https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/CWL_AnalyzeLogData_PPL.html) 和[CloudWatch Metrics Insights](https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/query_with_cloudwatch-metrics-insights.html)。

## 支持的 SQL 命令
<a name="CWL_AnalyzeLogData_SQL-table"></a>

**注意**  
在示例查询列中，根据需要替换 `<logGroup>`，具体取决于您要查询的数据来源。


| 命令或函数 | 示例查询 | 说明 | 
| --- | --- | --- | 
|  SELECT |  `SELECT `@message`, Operation FROM `LogGroupA``  |  显示预测值。  | 
|  FROM |  `SELECT `@message`, Operation FROM `LogGroupA``  |  内置子句，用于指定要从中检索数据的源表或视图，支持各种类型的联接和子查询。  | 
|  WHERE |  `SELECT * FROM `LogGroupA` WHERE Operation = 'x'`  |  根据提供的字段条件筛选日志事件。  | 
|  filterIndex |  `SELECT * FROM `filterIndex('region' = 'us-east-1')` WHERE status = 200 LIMIT 10;`  |  通过强制查询仅扫描在查询中指定的字段上建立索引的日志组，仅返回已编入索引的数据。  | 
|  GROUP BY |  `SELECT `@logStream`, COUNT(*) as log_count FROM `LogGroupA` GROUP BY `@logStream``  | 根据类别对日志事件进行分组，并根据统计数据计算平均值。  | 
|  HAVING |  `SELECT `@logStream`, COUNT(*) as log_count FROM `LogGroupA` GROUP BY `@logStream` HAVING log_count > 100`  |  根据分组条件筛选结果。  | 
|  ORDER BY |  `SELECT * FROM `LogGroupA` ORDER BY `@timestamp` DESC`  |  根据 ORDER BY 子句中的字段对结果进行排序。您可以按降序或升序进行排序。  | 
|  JOIN |  `SELECT A.`@message`, B.`@timestamp`FROM `LogGroupA` as A INNER JOIN `LogGroupB` as B ON A.`requestId` = B.`requestId``  |  根据共同字段合并两个表的结果。必须指定内部联接或左外联接  | 
|  LIMIT |  `Select * from `LogGroupA` limit 10`  |  将显示的查询结果限制为前 N 行。  | 
|  字符串函数 |  `SELECT upper(Operation) , lower(Operation), Operation FROM `LogGroupA``  |  SQL 中的内置函数，可在 SQL 查询中操作和转换字符串及文本数据。例如，转换大小写、合并字符串、提取部分内容以及清理文本。  | 
|  日期函数 |  `SELECT current_date() as today, date_add(current_date(), 30) as thirty_days_later, last_day(current_date()) as month_end FROM `LogGroupA``  |  内置函数，用于处理和转换 SQL 查询中的日期和时间戳数据。例如，date\$1add、date\$1format、datediff 和 current\$1date。  | 
|  条件函数 |  `SELECT Operation, IF(Error > 0, 'High', 'Low') as error_category FROM `LogGroupA`;`  |  内置函数，根据指定条件执行操作，或在特定条件下评估表达式。例如，CASE 和 IF。  | 
|  聚合函数 |  `SELECT AVG(bytes) as bytesWritten FROM `LogGroupA``  |  内置函数，可对多行数据执行计算以生成单个汇总值。例如，SUM、COUNT、AVG、MAX 和 MIN。  | 
|  JSON 函数 |  `SELECT get_json_object(json_column, '$.name') as name FROM `LogGroupA``  |  内置函数，用于在 SQL 查询中解析、提取、修改和查询 JSON 格式的数据（例如，from\$1json、to\$1json、get\$1json\$1object、json\$1tuple），支持对数据集中的 JSON 结构进行操作。  | 
|  数组函数 |  `SELECT scores, size(scores) as length, array_contains(scores, 90) as has_90 FROM `LogGroupA`;`  |  内置函数，用于在 SQL 查询中处理数组类型列，允许访问、修改和分析数组数据（例如，size、explode、array\$1contains）等操作。  | 
|  窗口函数 |  `SELECT field1, field2, RANK() OVER (ORDER BY field2 DESC) as field2Rank FROM `LogGroupA`;`  |  内置函数，可在当前行（窗口）相关的指定行集上执行计算，支持排名、运行总数和移动平均值等操作。例如，ROW\$1NUMBER、RANK、LAG 和 LEAD  | 
|  转换函数 |  `SELECT CAST('123' AS INT) as converted_number, CAST(123 AS STRING) as converted_string FROM `LogGroupA``  |  内置函数，在 SQL 查询中用于将数据从一种类型转换为另一种类型，支持数据类型转换和格式转换。例如，CAST、TO\$1DATE、TO\$1TIMESTAMP 和 BINARY。  | 
|  谓词函数 |  `SELECT scores, size(scores) as length, array_contains(scores, 90) as has_90 FROM `LogGroupA`;`  |  内置函数，用于计算条件，并根据指定的标准或模式返回布尔值（true/false）。例如，IN、LIKE、BETWEEN、IS NULL 和 EXISTS。  | 
|  选择多个日志组 |  `SELECT lg1.field1, lg1.field2 from `logGroups( logGroupIdentifier: ['LogGroup1', 'LogGroup2'])` as lg1 where lg1.field3= "Success"`  |  使您能够在 SELECT 语句中指定多个日志组  | 
|  选择多个数据源 |  `SELECT ds1.field1, ds1.field2 from `dataSource(['DataSource1', 'DataSource2'])` as ds1 where ds1.field3= "Success"`  |  使您能够在 SELECT 语句中指定多个数据源  | 

## 支持用于 multi-log-group查询的 SQL
<a name="CWL_AnalyzeLogData_SQL-multi"></a>

要支持在 SQL 中查询多个日志组的使用案例，可以使用 `logGroups` 命令。使用此语法，您可以通过在 FROM 命令中指定多个日志组来查询它们。

语法：

```
`logGroups(
    logGroupIdentifier: ['LogGroup1','LogGroup2', ...'LogGroupn']
)
```

在此语法中，您可在 `logGroupIdentifier` 参数中指定最多 50 个日志组。要引用监控账户中的日志组，请使用 ARNs 而不是`LogGroup`名称。

示例查询：

```
SELECT LG1.Column1, LG1.Column2 from `logGroups(
    logGroupIdentifier: ['LogGroup1', 'LogGroup2']
)` as LG1 WHERE LG1.Column1 = 'ABC'
```

查询日志时，不支持在语`FROM`句后面使用以下涉及多个 CloudWatch 日志组的语法。

```
SELECT Column1, Column2 FROM 'LogGroup1', 'LogGroup2', ...'LogGroupn'
WHERE Column1 = 'ABC'
```

## 支持用于数据源查询的 SQL
<a name="CWL_AnalyzeLogData_SQL-data-source"></a>

 要支持在 SQL 中查询数据源的用例，可以使用 dataSource 命令。使用此语法，您可以通过在`FROM`命令中指定数据源来查询数据源。您最多可以指定 10 个数据源。

**语法**

```
`dataSource(
    ['DataSource1', 'DataSource2', ...'DataSourcen']
)`
```

**查询示例**

```
SELECT DS1.Column1, DS1.Column2 from `dataSource(
    ['DataSource1', 'DataSource2']
)` as DS1 WHERE DS1.Column1 = 'ABC'
```

## 查询范围
<a name="CWL_AnalyzeLogData_SQL-scope"></a>

在 AWS CLI 和 API 中，您可以使用日志组、数据源和类型以及字段索引来指定要查询的日志。

### 日志组
<a name="CWL_AnalyzeLogData_SQL-scope-loggroup"></a>

当客户知道需要搜索哪些确切的日志组时，可以使用日志组来源选择

```
SELECT * FROM `logGroups(logGroupIdentifier: ['/aws/lambda/my-function'])`;
```

### 数据源和类型
<a name="CWL_AnalyzeLogData_SQL-scope-datasource"></a>

客户可以使用数据源名称和数据源类型查询日志。

当客户知道需要查询哪些确切的数据源时，可以使用基于数据源和类型的源选择。此查询是在一个或多个包含指定数据源和类型的日志组上执行的。

要支持在 SQL 中查询数据源的用例，可以使用 dataSource 命令。使用此语法，您可以通过在 FROM 命令中指定数据源来查询数据源。您最多可以指定 10 个数据源。

语法：

```
`dataSource(
    ['DataSource1.Type1', 'DataSource2.Type2', ...'DataSourcen.Typen']
)`
```

示例查询：

```
SELECT DS1.Column1, DS1.Column2 from `dataSource(
    ['DataSource1.Type1', 'DataSource2.Type2']
)` as DS1 WHERE DS1.Column1 = 'ABC'
```

有关按数据源进行查询的更多信息，请参阅[使用分面对日志进行分组和浏览](CloudWatchLogs-Facets.md)。

### 组合示例
<a name="CWL_AnalyzeLogData_SQL-scope-combined"></a>

客户可以在反引号中按任意顺序指定所有源选择运算符，结果将基于所应用的所有条件的交集。

例如，/aws/lambda/my-function-1 可能包含多个数据源和类型，包括各种各样的索引，当运行以下查询时，返回的结果将只有源和 DataSource类型 1.Type1 的事件，并且符合 “状态” = 200 的标准。

```
SELECT * FROM `
   logGroups(logGroupIdentifier: ['/aws/lambda/my-function'])
   filterIndex('status' = 200)
   dataSource(['DataSource1.Type1'])
`;
```

### 字段索引
<a name="CWL_AnalyzeLogData_SQL-scope-fieldindex"></a>

当您的筛选器针对索引字段时，基于字段索引的源选择会自动识别相关的日志组，从而减少扫描量和查询运行时间。

使用 `filterIndex` 可以强制查询仅扫描在查询中指定的字段上编制索引的日志组，从而返回已编制索引的数据 对于已在此字段上编制索引的日志组，它会进一步优化查询，跳过没有任何日志事件包含索引字段的查询中指定的字段的日志组。这样可以进一步减少扫描量，因为它会尝试仅扫描这些日志组中与此字段索引的查询中指定的值匹配的日志事件。有关字段索引及其创建方法的更多信息，请参阅[创建字段索引以提高查询性能和减少扫描量](CloudWatchLogs-Field-Indexing.md)。

在 SQL 中，filterIndex 用于指定应将哪些键值对视为索引。语法如下

```
SELECT * FROM `filterIndex('region' = 'us-east-1')`;
```

其中，

1. FilterIndex (...) 指定，将其中的键值视为字段索引。每个键值对用逗号分隔（以下示例）

1. 'region'='us-east-1'指定了要应用的实际条件

   1. 注意：客户可以使用 IN 来指定多个值，而不是 =（以下示例）

使用多个 FilterIndex 会使用 “AND” 组合条件。在示例中，将查询与 status=200 和 us-east-1 或 us-west-2 中的区域匹配的日志。

```
SELECT * FROM `filterIndex('status' = 200, 'region' IN ['us-east-1', 'us-west-2'])`;
```

## 限制
<a name="CWL_AnalyzeLogData_SQL-restrictions"></a>

当您使用 OpenSearch SQL 在 Lo CloudWatch gs Insights 中进行查询时，以下限制适用。
+ SELECT 语句中只能包含一个 JOIN。
+ 不能将 JOIN 或子查询用于数据源查询。
+ 仅支持一层嵌套子查询。
+ 不支持用分号（;）分隔的多语句查询。
+ 不支持包含相同但仅在大小写上不同的字段名称的查询（例如 field1 和 FIELD1）。

  例如，不支持以下查询：

  ```
  Select AWSAccountId, AwsAccountId from LogGroup
  ```

  然而，由于两个日志组中的字段名（`@logStream`）完全相同，因此支持以下查询：

  ```
  Select a.`@logStream`, b.`@logStream` from Table A INNER Join Table B on a.id = b.id
  ```
+ 函数和表达式必须对字段名进行操作，并作为包含在 FROM 子句中指定日志组的 SELECT 语句的一部分。

  例如，不支持此查询：

  ```
  SELECT cos(10) FROM LogGroup
  ```

  支持此查询：

  ```
  SELECT cos(field1) FROM LogGroup
  ```
+ 使用 SQL 或 PPL 命令时，需将特定字段用反引号括起来才能成功查询。包含特殊字符（非字母和非数字）的字段需要使用反引号。例如，对 `@message`、`Operation.Export` 和 `Test::Field` 使用反引号。纯字母名称的字段无需使用反引号。

  包含简单字段的查询示例：

  ```
  SELECT SessionToken, Operation, StartTime  FROM `LogGroup-A`
  LIMIT 1000;
  ```

  附加反引号的类似查询：

  ```
  SELECT `@SessionToken`, `@Operation`, `@StartTime`  FROM `LogGroup-A` LIMIT 1000;
  ```