

# 使用解释计划提高 Babelfish 查询性能
<a name="working-with-babelfish-usage-notes-features.using.explain"></a>

从版本 2.1.0 开始，Babelfish 包括两个函数，它们透明地使用 PostgreSQL 优化程序为 TDS 端口上的 T-SQL 查询生成估计和实际的查询计划。这些函数类似于对 SQL Server 数据库使用 SET STATISTICS PROFILE 或 SET SHOWPLAN\$1ALL 来识别和改进运行缓慢的查询。

**注意**  
目前不支持从函数、控制流程和游标获取查询计划。

在该表中，您可以找到跨 SQL Server、Babelfish 和 PostgreSQL 的查询计划解释函数的比较。


|  SQL Server  | Babelfish  | PostgreSQL  | 
| --- | --- | --- | 
| SHOWPLAN\$1ALL  | BABELFISH\$1SHOWPLAN\$1ALL  | EXPLAIN  | 
| STATISTICS PROFILE  | BABELFISH\$1STATISTICS PROFILE  | EXPLAIN ANALYZE  | 
| 使用 SQL Server 优化程序  | 使用 PostgreSQL 优化程序  | 使用 PostgreSQL 优化程序  | 
| SQL Server 输入和输出格式  | SQL Server 输入和 PostgreSQL 输出格式  | PostgreSQL 输入和输出格式  | 
| 为会话设置  | 为会话设置  | 应用于特定的语句  | 
| 支持以下各项： [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/AmazonRDS/latest/AuroraUserGuide/working-with-babelfish-usage-notes-features.using.explain.html)  | 支持以下各项： [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/AmazonRDS/latest/AuroraUserGuide/working-with-babelfish-usage-notes-features.using.explain.html)  | 支持以下各项： [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/AmazonRDS/latest/AuroraUserGuide/working-with-babelfish-usage-notes-features.using.explain.html)  | 

按如下方式使用 Babelfish 函数：
+ SET BABELFISH\$1SHOWPLAN\$1ALL [ON\$1OFF] – 设置为 ON 可生成估计的查询执行计划。此函数实现 PostgreSQL `EXPLAIN` 命令的行为。使用此命令获取给定查询的解释计划。
+ SET BABELFISH\$1STATISTICS PROFILE [ON\$1OFF] – 对于实际查询执行计划，设置为 ON。此函数实现 PostgreSQL 的 `EXPLAIN ANALYZE` 命令的行为。

有关 PostgreSQL `EXPLAIN` 和 `EXPLAIN ANALYZE` 的更多信息，请参阅 PostgreSQL 文档中的 [EXPLAIN](https://www.postgresql.org/docs/current/sql-explain.html)。

**注意**  
从版本 2.2.0 开始，您可以将 `escape_hatch_showplan_all` 参数设置为 *ignore*（忽略），以避免在 `SHOWPLAN_ALL` 和 `STATISTICS PROFILE` SET 命令的 SQL Server 语法中使用 *BABELFISH\$1* 前缀。

例如，以下命令序列开启查询规划，然后返回 SELECT 语句的估计查询执行计划而不运行查询。此示例通过 `northwind` 命令行工具查询 TDS 端口，以使用 SQL Server 示例 `sqlcmd` 数据库：

```
1> SET BABELFISH_SHOWPLAN_ALL ON
2> GO
1> SELECT t.territoryid, e.employeeid FROM
2> dbo.employeeterritories e, dbo.territories t
3> WHERE e.territoryid=e.territoryid ORDER BY t.territoryid;
4> GO

QUERY PLAN                                                                                                                                                                                                                                      
------------------------------------------------------------------------------------                                                                                                              
Query Text: SELECT t.territoryid, e.employeeid FROM
dbo.employeeterritories e, dbo.territories t
WHERE e.territoryid=e.territoryid ORDER BY t.territoryid
Sort  (cost=6231.74..6399.22 rows=66992 width=10)
  Sort Key: t.territoryid NULLS FIRST
  ->  Nested Loop  (cost=0.00..861.76 rows=66992 width=10)  
        ->  Seq Scan on employeeterritories e  (cost=0.00..22.70 rows=1264 width=4)
              Filter: ((territoryid)::"varchar" IS NOT NULL)
        ->  Materialize  (cost=0.00..1.79 rows=53 width=6)
              ->  Seq Scan on territories t  (cost=0.00..1.53 rows=53 width=6)
```

完成查询的检查和调整后，可以停用此函数，如下所示：

```
1> SET BABELFISH_SHOWPLAN_ALL OFF
```

将 BABELFIS\$1STATIONS PROFISATIONS 设置为 ON 时，每个执行的查询都会返回其常规结果集，然后是显示实际查询执行计划的附加结果集。Babelfish 生成的查询计划会在调用 SELECT 语句时提供最快的结果集。

```
1> SET BABELFISH_STATISTICS PROFILE ON
1>
2> GO
1> SELECT e.employeeid, t.territoryid FROM
2> dbo.employeeterritories e, dbo.territories t
3> WHERE t.territoryid=e.territoryid ORDER BY t.territoryid;
4> GO
```

返回结果集和查询计划（此示例仅显示查询计划）。

```
QUERY PLAN                                                                                                                                                                                                                                
---------------------------------------------------------------------------
Query Text: SELECT e.employeeid, t.territoryid FROM
dbo.employeeterritories e, dbo.territories t
WHERE t.territoryid=e.territoryid ORDER BY t.territoryid
Sort  (cost=42.44..43.28 rows=337 width=10)
  Sort Key: t.territoryid NULLS FIRST                                                                                                                                               
  ->  Hash Join  (cost=2.19..28.29 rows=337 width=10)
       Hash Cond: ((e.territoryid)::"varchar" = (t.territoryid)::"varchar")
        ->  Seq Scan on employeeterritories e  (cost=0.00..22.70 rows=1270 width=36)
        ->  Hash  (cost=1.53..1.53 rows=53 width=6)
             ->  Seq Scan on territories t  (cost=0.00..1.53 rows=53 width=6)
```

要了解有关如何分析查询以及 PostgreSQL 优化程序返回的结果的更多信息，请参阅 [explain.depesz.com](https://www.depesz.com/2013/04/16/explaining-the-unexplainable/)。有关 PostgreSQL EXPLAIN 和 EXPLAIN ANALYZE 的更多信息，请参阅 PostgreSQL 文档中的 [EXPLAIN](https://www.postgresql.org/docs/current/sql-explain.html)。

## 控制 Babelfish 解释选项的参数
<a name="working-with-babelfish-usage-notes-features.using.explain.parameters"></a>

您可以使用下表中显示的参数来控制查询计划显示的信息类型。


| 参数 | 描述 | 
| --- | --- | 
| babelfishpg\$1tsql.explain\$1buffers | 一个布尔值，用于打开（和关闭）优化程序的缓冲区使用信息。（原定设置值：关闭）（允许的值：关闭、打开）  | 
| babelfishpg\$1tsql.explain\$1costs | 一个布尔值，用于打开（和关闭）优化程序的估计启动和总成本信息。（原定设置值：打开）（允许的值：关闭、打开）  | 
| babelfishpg\$1tsql.explain\$1format | 指定 `EXPLAIN` 计划的输出格式。（原定设置值：text）（允许的值：text、xml、json、yaml）  | 
| babelfishpg\$1tsql.explain\$1settings | 一个布尔值，用于打开（或关闭）在 EXPLAIN 计划输出中包含有关配置参数的信息。（原定设置值：关闭）（允许的值：关闭、打开）  | 
| babelfishpg\$1tsql.explain\$1summary | 一个布尔值，用于打开（或关闭）摘要信息，例如查询计划后的总时间。（原定设置值：打开）（允许的值：关闭、打开）  | 
| babelfishpg\$1tsql.explain\$1timing | 一个布尔值，用于在输出中打开（或关闭）实际启动时间和每个节点花费的时间。（原定设置值：打开）（允许的值：关闭、打开）  | 
| babelfishpg\$1tsql.explain\$1verbose | 一个布尔值，用于打开（或关闭）解释计划的最详细版本。（原定设置值：关闭）（允许的值：关闭、打开）  | 
| babelfishpg\$1tsql.explain\$1wal | 一个布尔值，用于打开（或关闭）WAL 记录信息的生成，以作为解释计划的一部分。（原定设置值：关闭）（允许的值：关闭、打开）  | 

您可以使用 PostgreSQL 客户端或 SQL Server 客户端来检查系统上任何 BabelFish 相关参数的值。运行以下命令来获取当前参数值：

```
1> execute sp_babelfish_configure '%explain%';
2> GO
```

在以下输出中，您可以看到此特定 Babelfish 数据库集群上的所有设置均为原定设置值。此示例中并未显示所有输出。

```
             name                   setting                     short_desc
---------------------------------- -------- --------------------------------------------------------
babelfishpg_tsql.explain_buffers   off      Include information on buffer usage
babelfishpg_tsql.explain_costs     on       Include information on estimated startup and total cost
babelfishpg_tsql.explain_format    text     Specify the output format, which can be TEXT, XML, JSON, or YAML
babelfishpg_tsql.explain_settings  off      Include information on configuration parameters
babelfishpg_tsql.explain_summary   on       Include summary information (e.g.,totaled timing information) after the query plan 
babelfishpg_tsql.explain_timing    on       Include actual startup time and time spent in each node in the output
babelfishpg_tsql.explain_verbose   off      Display additional information regarding the plan
babelfishpg_tsql.explain_wal       off      Include information on WAL record generation

(8 rows affected)
```

可以使用 `sp_babelfish_configure` 更改这些参数的设置，如下例所示。

```
1> execute sp_babelfish_configure 'explain_verbose', 'on';
2> GO
```

如果您要在集群范围级别使设置永久化，请包括关键字 *server*，如以下示例所示。

```
1> execute sp_babelfish_configure 'explain_verbose', 'on', 'server';
2> GO
```