

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

# 查詢最佳化
<a name="query-optimize"></a>

## 中繼資料篩選條件
<a name="metadata-filters"></a>

當您查詢中繼資料或原始資料時，請使用 `WHERE`子句依中繼資料欄位篩選，以減少掃描的資料量。使用下列運算子來限制中繼資料掃描：
+ 等於 (=)
+ 不等於 (！=)
+ LIKE
+ IN
+ AND
+ 或

對於屬性屬性，請使用下列欄位來篩選結果：
+ `double_attribute_value`
+ `int_attribute_value`
+ `boolean_attribute_value`
+ `string_attribute_value`

這些欄位為屬性類型的資產屬性提供比 **latest\_value\_time\_series** 資料表更好的效能。

**注意**  
使用運算子右側的常值來正確限制資料掃描。例如，下列查詢的執行比使用嚴格的字串常值更差：  

```
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\_time\_series**、 **latest\_value\_time\_series**、**precomputed\_aggregates**) 都有與其資料列相關聯的時間戳記。除了中繼資料篩選條件之外，在 `event_timestamp` 欄位中使用`WHERE`子句篩選條件來減少掃描的資料量。使用下列操作來限制原始資料掃描：
+ 等於 (=)
+ 大於 (>)
+ 小於 (<)
+ 大於或等於 (>=)
+ 小於或等於 (<=)
+ BETWEEN
+ AND

**篩選條件的範例**：
+  查詢 **precomputed\_aggregates** 資料表時，請務必在 `WHERE`子句中指定品質篩選條件。這可減少查詢掃描的資料量，尤其是在尋找 `BAD`或 `UNCERTAIN`資料時。

   我們也強烈建議在查詢 **precomputed\_aggregates** 資料表時使用解析度篩選條件 (1 公尺、15 公尺、1 小時或 1 天）。如果您未指定解析度篩選條件， AWS IoT SiteWise 會預設為對所有解析度進行完整資料表掃描，這是無效的。
+  查詢原始資料時，也可以在 `WHERE`子句中使用時間戳記函數來篩選掃描的資料量。例如，下列查詢只會從 **raw\_time\_series** 資料表掃描最後 30 分鐘的資料：

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

**注意**  
不等於 `(!=)`且`OR`運算子通常不會將有意義的篩選條件套用至原始資料掃描。篩選原始資料值 (string\_value、double\_value 等） 也不會限制原始資料掃描。

## JOIN 最佳化
<a name="join-optimization"></a>

AWS IoT SiteWise SQL 支援將兩個資料表合併在一起的`JOIN`關鍵字。僅支援`JOIN`主動篩選欄位 （使用`ON`關鍵字） 的 。禁止完整笛卡爾聯結。

AWS IoT SiteWise 也支援隱含 `JOIN`而不使用 `JOIN`關鍵字。在不同中繼資料表和中繼資料表與原始資料表之間允許這些項目。例如，這個查詢：

```
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\_property | latest\_value\_time\_series | raw\_time\_series | precomputed\_aggregates | subquery | 
| --- | --- | --- | --- | --- | --- | --- | 
| 資產 | X | O | O | O | O | X | 
| asset\_property | O | X | O | O | O | X | 
| latest\_value\_time\_series | O | O | X | X | X | X | 
| raw\_time\_series | O | O | X | X | X | X | 
| precomputed\_aggregates | O | O | X | X | X | X | 
| subquery | X | X | X | X | X | X | 

盡可能使用隱含 `JOIN`。如果您必須使用 `JOIN`關鍵字，請在個別 `JOIN`ed 資料表上套用篩選條件，以將掃描的資料降至最低。例如， 而不是此查詢：

```
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`中的個別資料表。您也可以在子查詢中使用 `LIMIT`關鍵字以獲得相同的效果。

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

對於產生的資料列超過預設值的查詢，請將 [ExecuteQuery](https://docs.aws.amazon.com/iot-sitewise/latest/APIReference/API_ExecuteQuery.html) API 的頁面大小設定為最大值 20000。這可改善整體查詢效能。

使用 `LIMIT`子句來減少針對某些查詢掃描的資料量。請注意，彙總函數和某些全資料表子句 (`GROUP BY`、`ORDER BY`、`JOIN`) 需要完整掃描才能套用子`LIMIT`句。

**注意**  
 AWS IoT SiteWise 即使套用 `LIMIT`子句， 也可能會掃描最少量的資料，尤其是掃描多個屬性的原始資料查詢。