

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

# 查询优化
<a name="query-optimize"></a>

## 元数据过滤器
<a name="metadata-filters"></a>

查询元数据或原始数据时，使用`WHERE`子句按元数据字段进行筛选，以减少扫描的数据量。使用以下运算符来限制元数据扫描：
+ 等于（=）
+ 不等于（\$1=）
+ LIKE
+ IN
+ AND
+ 或

对于属性属性，请使用以下字段筛选结果。 :
+ `double_attribute_value`
+ `int_attribute_value`
+ `boolean_attribute_value`
+ `string_attribute_value`

对于属性类型的资产属性，这些字段的性能优于**最新的 value\$1time\$1series** 表。

**注意**  
使用运算符右侧的文字来正确限制数据扫描。例如，以下查询的性能比使用严格的字符串字面量差：  

```
SELECT property_id FROM asset_property WHERE property_name = CONCAT('my', 'property')
```

**Example 对于元数据过滤器：**  

```
SELECT p.property_name FROM asset_property p
WHERE p.property_type = 'attribute' AND p.string_attribute_value LIKE 'my-property-%'
```

## 原始数据过滤器
<a name="raw-data-filters"></a>

**所有原始数据表（**raw\$1time\$1series、latest\$1value\$1time\$1series** **、precomputed\$1aggrates）都有与其行关联的时间戳**。**除了元数据筛选器外，还可以在`event_timestamp`字段上使用`WHERE`子句筛选器来减少扫描的数据量。使用以下操作来限制原始数据扫描：
+ 等于（=）
+ 大于（>）
+ 小于（<）
+ 大于等于（>=）
+ 小于等于（<=）
+ BETWEEN
+ AND

**过滤器示例**：
+  查询 precom **puted\$1aggregates 表**时，请务必在子句中指定质量过滤器。`WHERE`这样可以减少查询扫描的数据量，尤其是在您要查找`BAD`或`UNCERTAIN`数据时。

   **我们还强烈建议在查询 precomputed\$1aggregates 表时使用分辨率过滤器（1m、15m、1h 或 1d）。**如果未指定分辨率过滤器， Amazon IoT SiteWise 则默认为对所有分辨率进行全表扫描，这样效率低下。
+  查询原始数据时，还可以在`WHERE`子句中使用时间戳函数来筛选扫描的数据量。例如，以下查询仅扫描 **raw\$1time\$1** series 表中最近 30 分钟的数据：

  ```
  SELECT r.event_timestamp, r.double_value
  FROM raw_time_series r
  WHERE r.event_timestamp > TIMESTAMP_SUB(MINUTE, 30, NOW())
  ```

**注意**  
不等于`(!=)`，`OR`运算符通常不会对原始数据扫描应用有意义的过滤器。对原始数据值（字符串值、double\$1value 等）进行筛选也不会限制原始数据扫描。

## 加入优化
<a name="join-optimization"></a>

Amazon IoT SiteWise SQL 支持使用`JOIN`关键字将两个表合并在一起。仅`JOIN`支持主动筛选字段（使用`ON`关键字）的。禁止使用完全笛卡尔联接。

Amazon IoT SiteWise 还支持不使用`JOIN`关键字的隐式 `JOIN` s。允许在不同的元数据表之间以及元数据表和原始表之间进行这些操作。例如，此查询：

```
SELECT a.asset_name, p.property_name FROM asset a, asset_property p
```

比这个等效的查询执行得更好：

```
SELECT a.asset_name, p.property_name FROM asset a
JOIN asset_property p ON a.asset_id = p.asset_id
```

允许使用以下隐式联接（允许 O，禁止 X）：


|  | asset | asset\$1property | latest\$1value\$1time\$1series | raw\$1time\$1series | precomputed\$1aggregates | subquery | 
| --- | --- | --- | --- | --- | --- | --- | 
| asset | X | O | O | O | O | X | 
| asset\$1property | O | X | O | O | O | X | 
| latest\$1value\$1time\$1series | O | O | X | X | X | X | 
| raw\$1time\$1series | O | O | X | X | X | X | 
| precomputed\$1aggregates | O | O | X | X | X | X | 
| subquery | X | X | X | X | X | X | 

尽可能使用隐式 `JOIN` s。如果必须使用`JOIN`关键字，请对各个 e `JOIN` d 表应用筛选器以最大限度地减少扫描的数据。例如，用以下查询代替这个查询：

```
SELECT level1.asset_id, level2.asset_id, level3.asset_id
FROM asset AS level1
JOIN asset AS level2 ON level2.parent_asset_id = level1.asset_id
JOIN asset AS level3 ON level3.parent_asset_id = level2.asset_id
WHERE level1.asset_name LIKE 'level1%'
AND level2.asset_name LIKE 'level2%'
AND level3.asset_name LIKE 'level3%'
```

使用这个更有效的查询：

```
SELECT level1.asset_id, level2.asset_id, level3.asset_id
FROM asset AS level1
JOIN (SELECT asset_id, parent_asset_id FROM asset WHERE asset_name LIKE 'level2%') AS level2 ON level2.parent_asset_id = level1.asset_id
JOIN (SELECT asset_id, parent_asset_id FROM asset WHERE asset_name LIKE 'level3%') AS level3 ON level3.parent_asset_id = level2.asset_id
WHERE level1.asset_name LIKE 'level1%'
```

通过将元数据过滤器推送到子查询中，可以确保在扫描过程中对 `JOIN` s中的各个表进行过滤。你也可以在子查询中使用`LIMIT`关键字来达到同样的效果。

## 大型查询
<a name="large-queries"></a>

对于生成的行数超过默认值的查询，请将 [ExecuteQuery](https://docs.amazonaws.cn/iot-sitewise/latest/APIReference/API_ExecuteQuery.html)API 的页面大小设置为最大值 20000。这提高了整体查询性能。

使用子`LIMIT`句可以减少为某些查询扫描的数据量。请注意，聚合函数和某些表范围的子句（`GROUP BY`、`ORDER BY`、`JOIN`）需要在应用子句之前进行全面扫描才能完成。`LIMIT`

**注意**  
 Amazon IoT SiteWise 即使应用了`LIMIT`子句，也可以扫描最少量的数据，特别是对于扫描多个属性的原始数据查询。