About me:Oracle ACE pro,optimistic,passionate and harmonious. Focus on ORACLE,MySQL and other database programming,peformance tuning,db design, j2ee,Linux/AIX,Architecture tech,etc
全部博文(172)
分类: Oracle
2023-05-08 15:26:58
CREATE OR REPLACE VIEW v1 AS
SELECT *
FROM employees
WHERE employee_id < 150;
CREATE OR REPLACE VIEW v2 AS
SELECT v1.employee_id employee_id, departments.department_id department_id
FROM v1, hr.departments
WHERE
v1.department_id = departments.department_id;
SELECT /*+ NO_MERGE(v2.v1) INDEX(v2.v1.employees idx_dept_id)
FULL(v2.departments) */ *
FROM v2
WHERE department_id = 30;
使用HINTS控制执行计划顺序:
1)leading或ordered是指定驱动表顺序,建议使用leading,更加灵活,ordered可能会导致笛卡尔积。
2)leading(a,b,c,d),use_nl(a,b,c,d)按照顺序做NESTED
LOOPS
3)leading(a,b,c,d),use_hash(a,b,c,d),a,b先做HASH JOIN,但是驱动表是CBO决定的,这时候{BANNED}最佳好配合swap_join_inputs指定driving table,no_swap_join_inputs非driving_table
4)use_nl和use_hash指定多个表,实际上等价于写多个use_nl或use_hash的单表,比如use_nl(a,b)<=>use_nl(a) use_nl(b)
5)对于use_nl,use_hash,use_merge必须指定leading或ordered,否则可能得不到想要的执行计划
下面看一个leading和use_hash的例子,是否有什么问题?
leading和use_hash,和前面的use_nl不同,它的驱动表的顺序是CBO决定的,比如按照字面理解上面的应该是A,B做HASH
JOIN,驱动表是A,然后结果与C做HASH JOIN,C被驱动,{BANNED}最佳后与D做HASH JOIN,D是被驱动的,但是实际上D是驱动表。这时候需要使用(no_)swap_join_inputs来指定驱动表(只针对HASH
JOIN有效),使用这个可以灵活控制HASH JOIN的驱动表,实现复杂HASH JOIN。
通过leading(a,b,c,d) use_hash(a,b,c,d) swap_join_inputs(a) no_swap_join_inputs(c) no_swap_join_inputs(d)确定hash join顺序是((A,B),C),D。