Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

planner: add document about some new introduced hints #14664

Merged
merged 7 commits into from
Aug 3, 2023
Merged
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
56 changes: 56 additions & 0 deletions optimizer-hints.md
ran-huang marked this conversation as resolved.
Show resolved Hide resolved
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这个 PR 需要完整地 cherrypick 到 7.1 和 6.5 吗?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

需要的

Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,16 @@ SELECT /*+ MERGE_JOIN(t1, t2) */ * FROM t1, t2 WHERE t1.id = t2.id;
>
> `MERGE_JOIN` 的别名是 `TIDB_SMJ`,在 3.0.x 及之前版本仅支持使用该别名;之后的版本同时支持使用这两种名称,但推荐使用 `MERGE_JOIN`。

### NO_MERGE_JOIN(t1_name [, tl_name ...])

`NO_MERGE_JOIN(t1_name [, tl_name ...])` 提示优化器对指定表不要使用 Sort Merge Join 算法。例如:

{{< copyable "sql" >}}

```sql
SELECT /*+ NO_MERGE_JOIN(t1, t2) */ * FROM t1, t2 WHERE t1.id = t2.id;
```

### INL_JOIN(t1_name [, tl_name ...])

`INL_JOIN(t1_name [, tl_name ...])` 提示优化器对指定表使用 Index Nested Loop Join 算法。这个算法可能会在某些场景更快,消耗更少系统资源,有的场景会更慢,消耗更多系统资源。对于外表经过 WHERE 条件过滤后结果集较小(小于 1 万行)的场景,可以尝试使用。例如:
Expand All @@ -105,10 +115,32 @@ SELECT /*+ INL_JOIN(t1, t2) */ * FROM t1, t2 WHERE t1.id = t2.id;
>
> `INL_JOIN` 的别名是 `TIDB_INLJ`,在 3.0.x 及之前版本仅支持使用该别名;之后的版本同时支持使用这两种名称,但推荐使用 `INL_JOIN`。

### NO_INDEX_JOIN(t1_name [, tl_name ...])

`NO_INDEX_JOIN(t1_name [, tl_name ...])` 提示优化器对指定表不要使用 Index Nested Loop Join 算法。例如:

{{< copyable "sql" >}}

```sql
SELECT /*+ NO_INDEX_JOIN(t1, t2) */ * FROM t1, t2 WHERE t1.id = t2.id;
```

### INL_HASH_JOIN

`INL_HASH_JOIN(t1_name [, tl_name])` 提示优化器使用 Index Nested Loop Hash Join 算法。该算法与 Index Nested Loop Join 使用条件完全一样,两者的区别是 `INL_JOIN` 会在连接的内表上建哈希表,而 `INL_HASH_JOIN` 会在连接的外表上建哈希表,后者对于内存的使用是有固定上限的,而前者使用的内存使用取决于内表匹配到的行数。

### NO_INDEX_HASH_JOIN(t1_name [, tl_name ...])

`NO_INDEX_HASH_JOIN(t1_name [, tl_name ...])` 提示优化器对指定表不要使用 Index Nested Loop Hash Join 算法。

### INL_MERGE_JOIN

`INL_MERGE_JOIN(t1_name [, tl_name])` 提示优化器使用 Index Nested Loop Merge Join 算法,该算法与 Index Nested Loop Join 使用条件完全一样。

### NO_INDEX_MERGE_JOIN(t1_name [, tl_name ...])

`NO_INDEX_MERGE_JOIN(t1_name [, tl_name ...])` 提示优化器对指定表不要使用 Index Nested Loop Merge Join 算法。

### HASH_JOIN(t1_name [, tl_name ...])

`HASH_JOIN(t1_name [, tl_name ...])` 提示优化器对指定表使用 Hash Join 算法。这个算法多线程并发执行,执行速度较快,但会消耗较多内存。例如:
Expand All @@ -123,6 +155,16 @@ SELECT /*+ HASH_JOIN(t1, t2) */ * FROM t1, t2 WHERE t1.id = t2.id;
>
> `HASH_JOIN` 的别名是 `TIDB_HJ`,在 3.0.x 及之前版本仅支持使用该别名;之后的版本同时支持使用这两种名称,推荐使用 `HASH_JOIN`。

### NO_HASH_JOIN(t1_name [, tl_name ...])

`NO_HASH_JOIN(t1_name [, tl_name ...])` 提示优化器对指定表不要使用 Hash Join 算法。例如:

{{< copyable "sql" >}}

```sql
SELECT /*+ NO_HASH_JOIN(t1, t2) */ * FROM t1, t2 WHERE t1.id = t2.id;
```

### HASH_JOIN_BUILD(t1_name [, tl_name ...])

`HASH_JOIN_BUILD(t1_name [, tl_name ...])` 提示优化器对指定表使用 Hash Join 算法,同时将指定表作为 Hash Join 算法的 Build 端,即用指定表来构建哈希表。例如:
Expand Down Expand Up @@ -941,3 +983,17 @@ EXPLAIN SELECT /*+ leading(t1, t3), inl_join(t3) */ * FROM t1, t2, t3 WHERE t1.i
+---------------------------------+----------+-----------+---------------+---------------------------------------------------------------------------------------------------------------------+
9 rows in set (0.01 sec)
```

### 使用 Hint 导致错误 `Can't find a proper physical plan for this query`

在下面几种情况下,可能会出现 `Can't find a proper physical plan for this query` 错误:

- 查询本身并不需要按顺序读取索引,即在不使用 Hint 的前提下,优化器在任何情况下都不会生成按顺序读取索引的计划。此时,如果指定了 `ORDER_INDEX` Hint,会出现此报错,此时应考虑移除对应的 `ORDER_INDEX` Hint。
- 使用 `NO_JOIN` 相关的 hint 排除了所有可能的 Join 方式。
ran-huang marked this conversation as resolved.
Show resolved Hide resolved

```sql
create table t1 (a int);
create table t2 (a int);
explain select /*+ no_hash_join(t1), no_merge_join(t1) */ * from t1, t2 where t1.a=t2.a;
ran-huang marked this conversation as resolved.
Show resolved Hide resolved
ERROR 1815 (HY000): Internal : Can't find a proper physical plan for this query
```