Files
oracle/tpt/ast/02_choosing_join_order.sql

112 lines
4.2 KiB
MySQL
Raw Normal View History

2026-03-12 21:23:47 +01:00
-- Copyright 2018 Tanel Poder. All rights reserved. More info at http://tanelpoder.com
-- Licensed under the Apache License, Version 2.0. See LICENSE.txt for terms & conditions.
--------------------------------------------------------------------------------
--
-- File name: 02_choosing_join_order.sql
--
-- Purpose: Advanced Oracle SQL Tuning demo script
-- Author: Tanel Poder
-- Copyright: (c) http://www.tanelpoder.com
--
-- Usage: You can run the query against Oracle's sample schemas (SH)
-- The optimizer stats have to be updated to cause trouble.
-- See the commented out code below
--
--------------------------------------------------------------------------------
-- in Oracle 11gR2, set the cardinality feedback option to false for demo stability purposes
-- alter session set "_optimizer_use_feedback"=false;
--
-- Set statistics_level = all for measuring optimizer misestimate (or use V$SQL_MONITOR):
-- alter session set statistics_level = all;
--
-- Cause trouble for the optimizer:
-- EXEC DBMS_STATS.SET_TABLE_STATS('SH','CUSTOMERS', NUMROWS=>1, NUMBLKS=>1, NO_INVALIDATE=>FALSE);
SELECT /*+ MONITOR */
ch.channel_desc
, co.country_iso_code co
, cu.cust_city
, p.prod_category
, sum(s.quantity_sold)
, sum(s.amount_sold)
FROM
sh.sales s
, sh.customers cu
, sh.countries co
, sh.products p
, sh.channels ch
WHERE
-- join
s.cust_id = cu.cust_id
AND cu.country_id = co.country_id
AND s.prod_id = p.prod_id
AND s.channel_id = ch.channel_id
-- filter
AND ch.channel_class = 'Direct'
AND co.country_iso_code = 'US'
AND p.prod_category = 'Electronics'
GROUP BY
ch.channel_desc
, co.country_iso_code
, cu.cust_city
, p.prod_category
/
--------------------------------------------------------------------------------------------------------
-- SQL Profiles (require Tuning + Diag Pack):
--------------------------------------------------------------------------------------------------------
--
-- VAR sql_fulltext CLOB
-- EXEC SELECT sql_fulltext INTO :sql_fulltext FROM v$sql WHERE sql_id = '1ka5g0kh4h6pc' AND rownum = 1;
--
-- Example 1: Set Join order:
-- EXEC DBMS_SQLTUNE.IMPORT_SQL_PROFILE(sql_text=>:sql_fulltext, profile=>sys.sqlprof_attr('LEADING(@"SEL$1" "CO"@"SEL$1" "CH"@"SEL$1" "CU"@"SEL$1" "S"@"SEL$1" "P"@"SEL$1")'), name=> 'MANUAL_PROFILE_1ka5g0kh4h6pc');
--
-- Example 2: Adjust cardinality:
-- EXEC DBMS_SQLTUNE.IMPORT_SQL_PROFILE(sql_text=>:sql_fulltext, profile=>sys.sqlprof_attr('CARDINALITY(@"SEL$1" "CU"@"SEL$1" 100000)'), name=> 'MANUAL_PROFILE_1ka5g0kh4h6pc');
--
-- Example 3: Set multiple hints:
-- DECLARE
-- hints sys.sqlprof_attr := sys.sqlprof_attr(
-- ('LEADING(@"SEL$1" "CO"@"SEL$1" "CH"@"SEL$1"')
-- , ('CARDINALITY(@"SEL$1" "CU"@"SEL$1" 100000)')
-- );
-- BEGIN
-- DBMS_SQLTUNE.IMPORT_SQL_PROFILE(sql_text=>:sql_fulltext, profile=> hints, name=> 'MANUAL_PROFILE_1ka5g0kh4h6pc');
-- END;
-- /
--
-- Drop the profile:
-- EXEC DBMS_SQLTUNE.DROP_SQL_PROFILE('MANUAL_PROFILE_1ka5g0kh4h6pc');
--
--
--------------------------------------------------------------------------------------------------------
-- SQL Plan Baselines - DBMS_SPM in EE licenses - see http://jonathanlewis.wordpress.com/2011/01/12/fake-baselines/
--------------------------------------------------------------------------------------------------------
-- bad_sqlid = 1ka5g0kh4h6pc
-- good_sqlid = 1fzf3vqv0f49q
-- 1) Manually run the query with hints, params, etc to get the plan you want (the good query)
--
-- 2) Create a disabled plan baseline for the "bad query":
-- VAR x NUMBER
-- EXEC :x:= DBMS_SPM.LOAD_PLANS_FROM_CURSOR_CACHE('&bad_sqlid', enabled=>'NO');
--
-- 3) SELECT sql_handle FROM dba_sql_plan_baselines WHERE sql_text = '<your sql_text>';
--
-- 4) Associate the "good query" plan with the "bad query" SQL plan baseline:
-- DEF good_sql_id = 1fzf3vqv0f49q
-- DEF good_plan_hash_value = 2863714589
-- DEF sql_handle_for_original = SQL_4b3ef772af37954d
-- VAR x NUMBER
--
-- exec :x := dbms_spm.load_plans_from_cursor_cache( -
-- sql_id => '&good_sql_id', -
-- plan_hash_value => &good_plan_hash_value, -
-- sql_handle => '&sql_handle_for_original');
--