

# 使用 T-SQL 查询提示提高 Babelfish 查询性能
<a name="babelfish-tsql-hints"></a>

从版本 2.3.0 开始，Babelfish 支持通过 `pg_hint_plan` 使用查询提示。在 Aurora PostgreSQL 中，原定设置情况下安装了 `pg_hint_plan`。有关 PostgreSQL 扩展 `pg_hint_plan` 的更多信息，请参阅 [https://github.com/ossc-db/pg_hint_plan](https://github.com/ossc-db/pg_hint_plan)。有关 Aurora PostgreSQL 支持的这一扩展的版本的详细信息，请参阅《Aurora PostgreSQL 发布说明》**中的 [Amazon Aurora PostgreSQL 的扩展版本](https://docs.aws.amazon.com/AmazonRDS/latest/AuroraPostgreSQLReleaseNotes/AuroraPostgreSQL.Extensions.html)。

 查询优化程序经过精心设计，可以找到 SQL 语句的最佳执行计划。选择计划时，查询优化程序会同时考虑引擎的成本模型以及列和表统计数据。但是，建议的计划可能无法满足数据集的需求。因此，查询提示解决了性能问题以改进执行计划。`query hint` 是 SQL 标准中添加的语法，用于指示数据库引擎如何执行查询。例如，提示可能会指示引擎进行顺序扫描并覆盖查询优化程序已选择的任何计划。

## 在 Babelfish 中开启 T-SQL 查询提示
<a name="babelfish-tsql-hints-turningon"></a>

目前，Babelfish 原定设置情况下忽略所有 T-SQL 提示。要应用 T-SQL 提示，请在将 enable\$1pg\$1hint 值设为 ON 的情况下运行命令 `sp_babelfish_configure`。

```
EXECUTE sp_babelfish_configure 'enable_pg_hint', 'on' [, 'server']
```

通过包含 *server* 关键字，可以在集群级别上使设置永久化。要仅为当前会话配置此设置，请不要使用 server。

开启 `enable_pg_hint` 后，Babelfish 会应用以下 T-SQL 提示。
+ INDEX 提示
+ JOIN 提示
+ FORCE ORDER 提示
+ MAXDOP 提示

例如，以下命令序列开启 `pg_hint_plan`。

```
1> CREATE TABLE t1 (a1 INT PRIMARY KEY, b1 INT);
2> CREATE TABLE t2 (a2 INT PRIMARY KEY, b2 INT);
3> GO    
1> EXECUTE sp_babelfish_configure 'enable_pg_hint', 'on';
2> GO
1> SET BABELFISH_SHOWPLAN_ALL ON;
2> GO
1> SELECT * FROM t1 JOIN t2 ON t1.a1 = t2.a2; --NO HINTS (HASH JOIN)
2> GO
```

不对 SELECT 语句应用任何提示。返回没有提示的查询计划。

```
QUERY PLAN                                                                                                                                                                                                                                
---------------------------------------------------------------------------
Query Text: SELECT * FROM t1 JOIN t2 ON t1.a1 = t2.a2
Hash Join (cost=60.85..99.39 rows=2260 width=16)
 Hash Cond: (t1.a1 = t2.a2)
 -> Seq Scan on t1 (cost=0.00..32.60 rows=2260 width=8)
 -> Hash (cost=32.60..32.60 rows=2260 width=8)
 -> Seq Scan on t2 (cost=0.00..32.60 rows=2260 width=8)
```

```
1> SELECT * FROM t1 INNER MERGE JOIN t2 ON t1.a1 = t2.a2;
2> GO
```

查询提示应用于 SELECT 语句。以下输出显示返回了带有合并联接的查询计划。

```
QUERY PLAN                                                                                                                                                                                                                                
---------------------------------------------------------------------------
Query Text: SELECT/*+ MergeJoin(t1 t2) Leading(t1 t2)*/ * FROM t1 INNER JOIN t2 ON t1.a1 = t2.a2
Merge Join (cost=0.31..190.01 rows=2260 width=16)
 Merge Cond: (t1.a1 = t2.a2)
 -> Index Scan using t1_pkey on t1 (cost=0.15..78.06 rows=2260 width=8)
 -> Index Scan using t2_pkey on t2 (cost=0.15..78.06 rows=2260 width=8)
```

```
1> SET BABELFISH_SHOWPLAN_ALL OFF;
2> GO
```

## 限制
<a name="babelfish-tsql-hints-limitations"></a>

使用查询提示时，请考虑以下限制：
+ 如果查询计划在开启 `enable_pg_hint` 之前已缓存，则不会在同一个会话中应用提示。它将在新会话中应用。
+ 如果显式给出了模式名称，则无法应用提示。您可以使用表别名作为解决方法。
+ 查询提示不能应用于视图和子查询。
+ 提示不适用于带有 JOIN 的 UPDATE/DELETE 语句。
+ 将忽略不存在的索引或表的索引提示。
+ FORCE ORDER 提示不适用于 HASH JOIN 和非 ANSI JOIN。