2026-03-12 20:23:15
This commit is contained in:
@@ -0,0 +1,96 @@
|
||||
-- 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.
|
||||
|
||||
|
||||
DEF schemaname=SOE1000G
|
||||
|
||||
GRANT SELECT ON sys.v_$session TO &schemaname;
|
||||
|
||||
-- DROP TABLE &schemaname..workload_control;
|
||||
-- DROP TRIGGER &schemaname..workload_control_trigger;
|
||||
|
||||
CREATE TABLE &schemaname..workload_control (
|
||||
username VARCHAR2(100) DEFAULT ('*') NOT NULL
|
||||
, service_name VARCHAR2(100) DEFAULT '*' NOT NULL
|
||||
, module VARCHAR2(100) DEFAULT '*' NOT NULL
|
||||
, action VARCHAR2(100) DEFAULT '*' NOT NULL
|
||||
, program VARCHAR2(100) DEFAULT '*' NOT NULL
|
||||
, client_machine VARCHAR2(100) DEFAULT '*' NOT NULL
|
||||
, client_osuser VARCHAR2(100) DEFAULT '*' NOT NULL
|
||||
, indexes_visible VARCHAR2(100) DEFAULT 'TRUE'
|
||||
, force_serial_direct_read VARCHAR2(100) DEFAULT 'FALSE'
|
||||
, CONSTRAINT pk_workload_control PRIMARY KEY (username, service_name, module, action, program, client_machine, client_osuser)
|
||||
, CONSTRAINT ck1_workload_control CHECK (indexes_visible IN ('TRUE','FALSE'))
|
||||
, CONSTRAINT ck2_workload_control CHECK (force_serial_direct_read IN ('TRUE', 'FALSE'))
|
||||
);
|
||||
|
||||
INSERT INTO &schemaname..workload_control (username, indexes_visible) VALUES ('&schemaname', 'TRUE');
|
||||
INSERT INTO &schemaname..workload_control (username, program, indexes_visible, force_serial_direct_read)
|
||||
VALUES ('&schemaname', 'sqlplus@mac02.local (TNS V1-V3)', 'FALSE', 'TRUE');
|
||||
COMMIT;
|
||||
|
||||
CREATE OR REPLACE TRIGGER &schemaname..workload_control_trigger
|
||||
AFTER LOGON ON &schemaname..SCHEMA
|
||||
DECLARE
|
||||
c NUMBER;
|
||||
BEGIN
|
||||
-- set optimizer_use_invisible_indexes
|
||||
FOR s IN (SELECT * FROM v$session WHERE sid = SYS_CONTEXT('userenv', 'sid'))
|
||||
LOOP -- this loop returns only 1 row
|
||||
SELECT COUNT(*) INTO c
|
||||
FROM &schemaname..workload_control ctl
|
||||
WHERE
|
||||
(ctl.username = s.username OR ctl.username = '*')
|
||||
AND (ctl.service_name = s.service_name OR ctl.service_name = '*')
|
||||
AND (ctl.module = s.module OR ctl.module = '*')
|
||||
AND (ctl.action = s.action OR ctl.action = '*')
|
||||
AND (ctl.program = s.program OR ctl.program = '*')
|
||||
AND (ctl.client_machine = s.machine OR ctl.client_machine = '*')
|
||||
AND (ctl.client_osuser = s.osuser OR ctl.client_osuser = '*')
|
||||
AND indexes_visible = 'FALSE';
|
||||
|
||||
IF c > 0 THEN
|
||||
EXECUTE IMMEDIATE 'alter session set optimizer_use_invisible_indexes = false';
|
||||
ELSE
|
||||
EXECUTE IMMEDIATE 'alter session set optimizer_use_invisible_indexes = true';
|
||||
END IF;
|
||||
END LOOP;
|
||||
|
||||
-- set _serial_direct_read
|
||||
FOR s IN (SELECT * FROM v$session WHERE sid = SYS_CONTEXT('userenv', 'sid'))
|
||||
LOOP -- this loop returns only 1 row
|
||||
SELECT COUNT(*) INTO c
|
||||
FROM &schemaname..workload_control ctl
|
||||
WHERE
|
||||
(ctl.username = s.username OR ctl.username = '*')
|
||||
AND (ctl.service_name = s.service_name OR ctl.service_name = '*')
|
||||
AND (ctl.module = s.module OR ctl.module = '*')
|
||||
AND (ctl.action = s.action OR ctl.action = '*')
|
||||
AND (ctl.program = s.program OR ctl.program = '*')
|
||||
AND (ctl.client_machine = s.machine OR ctl.client_machine = '*')
|
||||
AND (ctl.client_osuser = s.osuser OR ctl.client_osuser = '*')
|
||||
AND force_serial_direct_read = 'TRUE';
|
||||
|
||||
IF c > 0 THEN
|
||||
EXECUTE IMMEDIATE 'alter session set "_serial_direct_read" = ALWAYS';
|
||||
END IF;
|
||||
END LOOP;
|
||||
END;
|
||||
/
|
||||
|
||||
SHOW ERR
|
||||
|
||||
-- set all indexes invisible in your hybrid-workload schema
|
||||
ALTER SESSION SET ddl_lock_timeout = 10;
|
||||
BEGIN
|
||||
FOR i IN (SELECT index_name FROM user_indexes
|
||||
WHERE table_name NOT IN 'WORKLOAD_CONTROL'
|
||||
AND table_owner NOT IN ('SYS', 'SYSTEM')
|
||||
AND table_owner = '&schemaname'
|
||||
AND visibility = 'VISIBLE')
|
||||
LOOP
|
||||
EXECUTE IMMEDIATE 'ALTER INDEX '||i.index_name||' INVISIBLE';
|
||||
END LOOP;
|
||||
END;
|
||||
/
|
||||
|
||||
@@ -0,0 +1,73 @@
|
||||
-- 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.
|
||||
|
||||
-- DROP TABLE test_users;
|
||||
-- DROP TABLE test_objects;
|
||||
|
||||
CREATE TABLE test_users AS SELECT * FROM all_users;
|
||||
CREATE TABLE test_objects AS SELECT * FROM all_objects;
|
||||
|
||||
CREATE INDEX i_test_users ON test_users (username);
|
||||
CREATE INDEX i_test_objects ON test_objects (owner);
|
||||
|
||||
EXEC DBMS_STATS.GATHER_TABLE_STATS(user,'TEST_USERS');
|
||||
EXEC DBMS_STATS.GATHER_TABLE_STATS(user,'TEST_OBJECTS');
|
||||
|
||||
PROMPT ==================================================================================
|
||||
PROMPT This plan should use indexes as they are visible and available:
|
||||
PROMPT ==================================================================================
|
||||
|
||||
SELECT
|
||||
SUM(u.user_id) + SUM(o.object_id)
|
||||
FROM
|
||||
test_users u
|
||||
, test_objects o
|
||||
WHERE
|
||||
u.username = o.owner
|
||||
AND u.username LIKE 'S%'
|
||||
AND o.owner LIKE 'S%'
|
||||
/
|
||||
|
||||
SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY_CURSOR);
|
||||
|
||||
PROMPT ==================================================================================
|
||||
PROMPT Making indexes invisible. The plan should use FULL TABLE scans now:
|
||||
PROMPT ==================================================================================
|
||||
|
||||
ALTER INDEX i_test_users INVISIBLE;
|
||||
ALTER INDEX i_test_objects INVISIBLE;
|
||||
ALTER SESSION SET optimizer_use_invisible_indexes = false;
|
||||
|
||||
SELECT
|
||||
SUM(u.user_id) + SUM(o.object_id)
|
||||
FROM
|
||||
test_users u
|
||||
, test_objects o
|
||||
WHERE
|
||||
u.username = o.owner
|
||||
AND u.username LIKE 'S%'
|
||||
AND o.owner LIKE 'S%'
|
||||
/
|
||||
|
||||
SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY_CURSOR);
|
||||
|
||||
PROMPT ==================================================================================
|
||||
PROMPT Setting optimizer_use_invisible_indexes = TRUE. The plan should use indexes again:
|
||||
PROMPT ==================================================================================
|
||||
|
||||
ALTER SESSION SET optimizer_use_invisible_indexes = true;
|
||||
|
||||
SELECT
|
||||
SUM(u.user_id) + SUM(o.object_id)
|
||||
FROM
|
||||
test_users u
|
||||
, test_objects o
|
||||
WHERE
|
||||
u.username = o.owner
|
||||
AND u.username LIKE 'S%'
|
||||
AND o.owner LIKE 'S%'
|
||||
/
|
||||
|
||||
SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY_CURSOR);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user