在有些场景,优化器并不一定会选择最优的执行计划,此时可以通过hint来固定执行计划,让优化器选择指定的方式执行。
常见的有以下一些情况:
使用hint指定关联方式
可能会发现,有此场景优化器没有没有使用最优的关联方式,可以通过hint来固化,例如,使用hint指定hashjoin:
select /*+hashjoin(table1, table2)*/
有时候SQL比较复杂,hint方式指定了hashjoin,优化器还是走了nestedloop,可以通过设置SQL对应的参数来调整:
select /*+ set (enable_nestloop off)*/ xxx
使用hint开启并行
当SQL中存在大表全表扫描,可以尝试通过hint方式开启并行。
- 对单个表加并行:
select /* +parallel(table_name 8) */ xxx;
- 对多个表加并行:
select /*+parallel(table_name1 8) parallel(table_name2 8)*/ xxx;
常用hint表:
分类 | 格式 | 说明 |
---|---|---|
扫描方法 | SeqScan(table) | 强制对指定表使用序列扫描。 |
TidScan(table) | 强制对指定表使用TID扫描。 | |
IndexScan(table[ index...]) | 强制对指定表使用索引扫描,可以指定某个索引。 | |
IndexOnlyScan(table[ index...]) | 强制对指定表仅使用索引扫描,可以指定某个索引。 | |
BitmapScan(table[ index...]) | 强制对指定表使用位图扫描,可以指定某个索引。 | |
IndexScanRegexp(table[ POSIX Regexp...]) | 强制对指定表使用索引扫描或仅索引扫描或位图扫描。使用正则匹配。 | |
IndexOnlyScanRegexp(table[ POSIX Regexp...]) | ||
BitmapScanRegexp(table[ POSIX Regexp...]) | ||
NoSeqScan(table) | 对指定表禁止使用序列扫描。 | |
NoTidScan(table) | 对指定表禁止使用TID扫描。 | |
NoIndexScan(table) | 对指定表禁止使用索引扫描(包括仅索引扫描)。 | |
NoIndexOnlyScan(table) | 对指定表禁止使用仅索引扫描。 | |
NoBitmapScan(table) | 对指定表禁止使用位图扫描。 | |
连接方法 | NestLoop(table table[ table...]) | 强制对指定表使用嵌套循环连接。 |
HashJoin(table table[ table...]) | 强制对指定表使用哈希连接。 | |
MergeJoin(table table[ table...]) | 强制对指定表使用合并连接。 | |
NoNestLoop(table table[ table...]) | 对指定表禁止使用嵌套循环连接。 | |
NoHashJoin(table table[ table...]) | 对指定表禁止使用哈希连接。 | |
NoMergeJoin(table table[ table...]) | 对指定表禁止使用合并连接 | |
连接顺序 | Leading(table table[ table...]) | 强制连接顺序。 |
Leading( |
强制连接顺序和方向, | |
行号校正 | Rows(table table[ table...] correction) | 纠正由指定表组成的联接结果的行号。可用的校正方法有绝对值(# |
并行查询配置 | Parallel(table <# of workers> [soft | hard]) |
GUC | Set(GUC-param value) | 计划器运行时,设置GUC参数。 |