Hint 的常见错误使用方式
提起 Oracle 数据库的 Hint,几乎每一个 DBA 都知道这一强大工具。在 Oracle 中,Hint 可以
用来改变 SQL 的执行计划、固定 SQL 的执行计划。Oracle 数据库内部的很多特性也依赖于
Hint,比如 Outline、Profile 等。
但是在日常工作中,很多开发人员或 DBA,对 Hint 的使用仍然存在一些错误的方式。下面
将列举主要的 2 种。(本文不讨论 Hint 的滥用即过度使用问题)。
1. NOLOGGING 的不正确使用。
很多人知道,在进行数据处理时,如果不产生日志或只产生少量的日志,将会有明显的、甚
至是巨大的效率提升。下面有几条不同的 SQL:
view plain copy to clipboard print ?
INSERT INTO T1 NOLOGGING;
INSERT INTO T1 SELECT * FROM T2 NOLOGGING;
INSERT /*+ NOLOGGING */ INTO T1 VALUES ('0');
INSERT /*+ NOLOGGING */ INTO T1 SELECT * FROM T2;
DELETE /*+ NOLOGGING */ FROM T1;
UPDATE /*+ NOLOGGING */ T1 SET A='1';
实际上,上述所有的 SQL 没有一个能够实现“不产生”日志的数据更改操作。第 1-2 条 SQL
语句虽然没有将 NOLOGGING 写为 Hint 的形式,但是也是很多人的错误写法,一并列在此
处。事实上,NOLOGGING 并不是 Oracle 的一个有效的 Hint,而是一个 SQL 关键字,通常
用于 DDL 语句中。这里 NOLOGGING 相当于给 SELECT 的表指定了一个别名为“NOLOGGING”。
下面是 NOLOGGING 的一些正确用法:
view plain copy to clipboard print ?
CREATE TABLE T1 NOLOGGING AS SELECT * FROM T2;
CREATE INDEX T1_IDX ON T1(A) NOLOGGING;
ALTER INDEX T1_IDX REDUILD ONLINE NOLOGGING;
ALTER TABLE T1 NOLOGGING;
上述 SQL 中,最后一条 SQL 只是将表的 LOGGING 属性改为"NO"。而之前的几条 SQL 能够
有效地减少 DDL 操作时减少的日志量。
在 DML 操作中,只有下面一种方式能够在大数据量时仍然只会产生极少量的日志:
view plain copy to clipboard print ?
INSERT /*+ APPEND */ INTO T1 SELECT * FROM T2;
也就是使用 append hint。但是这个 hint 要达到目的,需要以下几个条件:
使用 INSERT /*+ APPEND */ INTO .. SELECT .. FROM 形式的 INSERT SQL。
如果是在归档模式下,需要将表的 LOGGING 属性置为 NO。
表空间或数据库的 FORCE LOGGING 属性为 NO。注意在非归档模式下也是可以设置 FORCE
LOGGING 的。
评论