已知SQL更好执行计划的调优
1.创建测试表及数据
CREATE TABLE T01(ID NUMBER,NAME VARCHAR2(20));
CREATE INDEX IDX_T01_ID ON T01(ID);
INSERT INTO T01 VALUES (1,'MONKEY');
INSERT INTO T01 VALUES (2,'MONKEY');
INSERT INTO T01 VALUES (3,'MONKEY');
INSERT INTO T01 VALUES (4,'MONKEY');
INSERT INTO T01 VALUES (5,'MONKEY');
COMMIT;
2.根据ID查询测试表并查看执行计划
SELECT * FROM MONKEY.T01 WHERE ID = 2;
SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY_CURSOR(NULL,NULL,'Advanced'))
3.自己加hint,生成更好的执行计划
SELECT /*+FULL(A)*/* FROM MONKEY.T01 A WHERE ID = 2;
SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY_CURSOR(NULL,NULL,'Advanced'))
4.提取对应的执行计划
/* Formatted on 2021-05-20 下午 02:51:45 (QP5 v5.163.1008.3004) */
SELECT 'q''['
|| REPLACE (EXTRACTVALUE (VALUE (d), '/hint'), '', '''')
|| ']'','
AS outline_hints
FROM XMLTABLE (
'/*/outline_data/hint'
PASSING (SELECT xmltype (other_xml) AS xmlval
FROM v$sql_plan
WHERE sql_id = '4ym6mvwvuduha' ------sql_Id is which you get profile
AND child_number = 0
AND other_xml IS NOT NULL)) d;
在实践过程中,可能会出现隔得太久,执行计划已经被踢出sharepool的情况,此时就需要从DBA_HIST_SQL_PLAN抓取执行计划
SELECT 'q''['
|| REPLACE (EXTRACTVALUE (VALUE (d), '/hint'), '', '''')
|| ']'','
AS outline_hints
FROM XMLTABLE (
'/*/outline_data/hint'
PASSING (SELECT xmltype (other_xml) AS xmlval
FROM DBA_HIST_SQL_PLAN
WHERE sql_id = '4x90hmraqdjf9' ------sql_Id is which you get profile
AND PLAN_HASH_VALUE = 3651047320 --这里需要用PLAN_HASH_VALUE
AND other_xml IS NOT NULL)) d;
5.用生成的执行计划替换原有的计划
/* Formatted on 2021-05-20 下午 02:56:44 (QP5 v5.163.1008.3004) */
DECLARE
V_SQLID_1 V$SQL.SQL_ID%TYPE := '2a7npa11xs7st'; -------------sql_Id is which you want to change
V_CHILDNO_1 V$SQL.CHILD_NUMBER%TYPE := 0;
v_sqlprofile SYS.sqlprof_attr;
v_new_profile_name VARCHAR2 (255);
v_sql_text V$SQL.SQL_FULLTEXT%TYPE;
BEGIN
SELECT sql_fulltext
INTO v_sql_text
FROM v$sql
WHERE sql_id = V_SQLID_1 AND child_number = V_CHILDNO_1;
SELECT 'coe_' || DBMS_RANDOM.STRING ('A', 24)
INTO v_new_profile_name
FROM DUAL;
DBMS_SQLTUNE.import_sql_profile (
sql_text => v_sql_text,
name => v_new_profile_name,
profile => sqlprof_attr (q'[IGNORE_OPTIM_EMBEDDED_HINTS]',
q'[OPTIMIZER_FEATURES_ENABLE('11.2.0.4')]',
q'[DB_VERSION('11.2.0.4')]',
q'[ALL_ROWS]',
q'[OUTLINE_LEAF(@"SEL$1")]',
q'[FULL(@"SEL$1" "A"@"SEL$1")]'),
REPLACE => TRUE,
force_match => TRUE);
END;
/
6.查看是否替换成功
SELECT A.EXECUTIONS,A.SQL_PROFILE FROM V$SQLAREA A WHERE A.SQL_ID='2a7npa11xs7st';
再次执行sql后,SQL_PROFILE栏位会有数据。
/*+
PUSH_PRED(X 2)
OUTLINE_LEAF()
*/
7.其他
删除sql profile
exec dbms_sqltune.drop_sql_profile('SYS_SQLPROF_014b39f084c88000');
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 使用C#创建一个MCP客户端
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 按钮权限的设计及实现
2020-05-20 oracle字符集与乱码(转)