说明 1.整理了一些本人平时SQL 调优中常用到的一些Hint,方便大家参考
2.Hint相关文章地址:
Oracle Hint之概念与用法: http://blog.itpub.net/69992972/viewspace-2756965/
Oracle Hint之常用Hint功能概述(一): http://blog.itpub.net/69992972/viewspace-2757087/
Oracle Hint之常用Hint功能概述(二): http://blog.itpub.net/69992972/viewspace-2757182/
Oracle Hint之常用Hint功能概述(三): http://blog.itpub.net/69992972/viewspace-2757238/
Oracle Hint之常用Hint功能概述(四): http://blog.itpub.net/69992972/viewspace-2757242/
Oracle Hint之常用Hint功能概述(五): http://blog.itpub.net/69992972/viewspace-2757273/ 索引Hint
|
Hint 名 |
功能概述 |
举例 |
|
/*+ index(tab idx_name) */ |
使优化器对指定的表使用索引扫描。可用于函数、域(domain)、 B-tree, bitmap 和 bitmap join索引等 |
SELECT /*+ INDEX (employees department_idx)*/ employee_id, department_id FROM emp WHERE department_id > 20; |
|
/*+ no_index(tab idx_name) */ |
强制优化器不使用指定的索引扫描 |
|
|
/*+ index_join(tab idx_name) */ |
让优化器使用指定的索引作为访问路径进行索引关联。不同之处是select语句中查询列必须包含在索引中,可避免回表。因为当谓词中的列都有索引时,可直接通过索引关联,而这个hint可以将同一张表的不同索引进行合并,优化器只需扫描这些索引即可,不需要回表 |
SELECT /*+ INDEX_JOIN(t manager_idx department_idx) */ department_id FROM emp t WHERE manager_id < 100 AND department_id < 20; |
|
/*+ index_ffs(tab idx_name) */ |
强制优化器对指定索引使用Fast Full Scan方式扫描。但是必须select语句中查询列必须包含在索引中,可避免回表 |
|
|
/*+ index_ss(tab idx_name) */ |
强制优化器对指定索引使用Skip Scan方式扫描 |
|
|
/*+ index_asc(tab idx_name) */ |
使优化器对指定的表使用索引扫描。一般来说该hint不会更改索引的默认顺序,但如果该语句使用索引范围(index range scan)扫描,则Oracle数据库将按其索引值的升序扫描索引条目 |
|
|
/*+ index_desc(tab idx_name) */ |
使优化器对指定的表使用降序索引扫描。如果该语句使用索引范围扫描并且索引在升序,则按索引值的降序扫描索引条目。在分区索引中,结果在每个分区中按降序排列。对于降序索引,该hint有效地抵消了降序,从而以升序扫描了索引条目 |
|
|
/*+ index_combine(tab idx_name) */ |
该hint可以使用任何类型的索引:bitmap,B-tree,或domain。如果未指定索引名,那么优化器将隐式地将INDEX hint应用于所有索引,并使用尽可能多的索引。如果指定索引名,则优化器将使用所有合法且有效的在hint中提到的索引,而不考虑成本 |
SELECT /*+ INDEX_COMBINE(t manager_idx department_idx) */ * FROM emp t WHERE manager_id = 10 OR department_id = 20; |
表连接Hint
|
Hint 名 |
功能概述 |
举例 |
|
/*+ ordered */ |
该hint让优化器按照表在FROM子句中出现的顺序联接表。Oracle官方建议使用LEADING hint,该提示比ORDERED提示更通用。当从需要联接的SQL语句中省略ORDERED提示时,优化程序将选择联接表的顺序。如果用户知道优化器不了解有关从每个表中选择的行数的信息,则可能需要使用ORDERED hint来指定连接顺序。这样可以让用户比优化器更好地选择内部和外部表 |
SELECT /*+ ORDERED */ o.order_id, c.customer_id, i.unit_price * i.quantity FROM customers c, items i, orders o WHERE c.cust_last_name = 'Smith' AND o.customer_id = c.customer_id AND o.order_id = i.order_id; |
|
/*+ leading(tab1 tab2) */ |
该hint是一个多表hint,可以指定多个表或视图。 LEADING指示优化器将指定的表集用作执行计划中的前缀。指定的第一个表用于启动联接 |
SELECT /*+ LEADING(e j) */ * FROM emp e, departments d, job_history j WHERE e.department_id = d.department_id AND e.hire_date = j.start_date; |
|
/*+ use_nl(tab1 tab2) */ |
USE_NL提示指示优化器将指定的表用作内部表(被驱动表),以嵌套循环联接的方式将每个指定的表连接至另一个行源。建议在LEADING和ORDERED这两个hint中来使用USE_NL和USE_MERGE hint。当强制将引用表作为联接的内部表时,优化器将使用这些hint。 如果引用的表是外部表,则忽略该hint |
SELECT /*+ USE_NL(i h) */ h.customer_id, i.unit_price * i.quantity FROM orders h, items i WHERE l.order_id = h.order_id; |
|
/*+ use_nl_with_index(tab idx_name) */ |
该hint让优化器使用指定的表作为内部表,使用嵌套循环连接(NL)将指定的表连接到另一个行源 |
SELECT /*+ USE_NL_WITH_INDEX(i item_product_ix) */ * FROM orders h, items i WHERE i.order_id = h.order_id AND i.order_id > 2400; |
|
/*+ use_merge(tab1 tab2) */ |
该hint让优化器使用排序合并联接(SMJ)将每个指定的表作为被驱动表与另一个行源联接 |
SELECT /*+ USE_MERGE(employees departments) */ * FROM employees, departments WHERE employees.department_id = departments.department_id; |
|
/*+ use_hash(tab1 tab2) */ |
该hint让优化器使用哈希联接将每个指定的表与另一个行源联接 |
SELECT /*+ USE_HASH(l h) */ * FROM orders h, items i WHERE i.order_id = h.order_id AND i.order_id > 2400; |
|
/*+ driving_site(tab) */ |
该hint让优化器在与数据库选择的节点不同的节点上(其他节点生效)执行查询。适用于CBO和RBO。如果使用的是带DBLINK的分布式查询优化,则此hint会大大节省网络传输的数据量,但不能用于分布式DML和DDL |
SELECT /*+ DRIVING_SITE(departments) */ * FROM emp e, departments@testdb WHERE e.department_id = departments.department_id; |
|
/*+ use_concat */ |
该hint让优化器使用UNION ALL set运算符将查询的WHERE子句中的组合OR条件转换为复合查询(union all)。 如果没有此hint,则仅当在使用串联的查询的成本比没有串联的成本低时,才会发生此转换。 该hint覆盖了成本考虑因素 |
SELECT /*+ USE_CONCAT */ * FROM emp e WHERE manager_id = 1 OR department_id = 20; |
|
/*+ merge_aj */ |
针对有子查询的SQL,让优化器强制执行排序合并反连接 |
|
|
/*+ hash_aj */ |
针对有子查询的SQL,让优化器强制执行HASH反连接 |
|
|
/*+ nl_aj */ |
针对有子查询的SQL,让优化器强制执行嵌套循环反连接 |
|
|
/*+ merge_sj */ |
针对有子查询的SQL,让优化器强制执行排序合并半连接 |
|
|
/*+ hash_sj */ |
针对有子查询的SQL,让优化器强制执行HASH半连接 |
|
|
/*+ nl_sj */ |
针对有子查询的SQL,让优化器强制执行嵌套循环半连接 |
注: 1. 表中所说的“行源”就是表的关联列(连接列)2. 对于/*+ no_use_xxx */这种hint,就是/*+ use_xxx */的“反义词”,比如/*+ no_use_merge */,这里就不多赘述了
