博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Oracle一条SQL语句时快时慢
阅读量:6442 次
发布时间:2019-06-23

本文共 3769 字,大约阅读时间需要 12 分钟。

  今天碰到一个非常奇怪的问题问题,一条SQL语句在PL/SQL developer中很慢,需要9s,问题SQL:

   SELECT * FROM GG_function_location f WHERE f.parent_id ='03000000000001';  表GG_function_location有5千万的数据,parent_id上是有索引的。

   诊断第一步:就在PL/SQL developer中按F5,看到的执行计划是走索引的,应该不会慢啊。

   第二步:在sqlplus中用autotrace看,非常快,0.06s。

   第三部:我想要重现这种慢,于是在PL/SQL developer中开一个窗口,天啊!单独执行SQL非常慢,但使用下面的语句就非常快,真是太神奇了。

     alter session set tracefile_identifier = 'gg_test';

     alter session set events '10046 trace name context forever ,level 12' ;
     SELECT * FROM GG_function_location f WHERE f.parent_id ='03000000000001' ;
     alter session set events '10046 trace name context off' ;

   第四部:我想到v$sql中找到这条SQL的执行计划,终于有了发现。

SQL> select banner from v$version;

BANNER
--------------------------------------------------------------------------------
Oracle Database 12c Enterprise Edition Release 12.1.0.1.0 - 64bit Production
PL/SQL Release 12.1.0.1.0 - Production
CORE    12.1.0.1.0      Production
TNS for Linux: Version 12.1.0.1.0 - Production
NLSRTL Version 12.1.0.1.0 - Production

SQL> select s.SQL_TEXT,s.SQL_ID

      from v$sql s
     where s.SQL_TEXT like
           'SELECT * FROM GG_function_location f WHERE f.parent_id =%'
       and s.SQL_TEXT not like '%AND%';
SQL_TEXT                                                                   SQL_ID
-------------------------------------------------------------------------  ------------
SELECT * FROM GG_function_location f WHERE f.parent_id ='03000000000001'  dk02nb8mkchna
SELECT * FROM GG_function_location f WHERE f.parent_id ='03000000000001'  2zav8x5kwxb32
SELECT * FROM GG_function_location f WHERE f.parent_id ='03000000000001'  bc0k800k6u0x3

先找到SQL_ID,再找到对应的执行计划

select hash_value, child_number, sql_text from v$sql s
 where s.SQL_ID = 'bc0k800k6u0x3';
select * from table(dbms_xplan.display_cursor(611124131, 0, 'advanced'));
执行计划一:
HASH_VALUE  656818826, child number 0
-------------------------------------
SELECT * FROM GG_function_location f WHERE f.parent_id ='03000000000001'
Plan hash value: 1550360901
-----------------------------------------------------------------------------------------------------------------------------------
| Id  | Operation                                  | Name                 | Rows  | Bytes | Cost (%CPU)| Time     | Pstart| Pstop |
-----------------------------------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT                           |                      |       |       |     7 (100)|          |       |       |
|   1 |  TABLE ACCESS BY GLOBAL INDEX ROWID BATCHED| GG_FUNCTION_LOCATION |     3 |   999 |     7   (0)| 00:00:01 | ROWID | ROWID |
|*  2 |   INDEX RANGE SCAN                         | IDX_GG_FL_PARENT_ID  |     3 |       |     4   (0)| 00:00:01 |       |       |
-----------------------------------------------------------------------------------------------------------------------------------
执行计划二: 
HASH_VALUE  611124131, child number 0
-------------------------------------
SELECT * FROM GG_function_location f WHERE f.parent_id ='03000000000001'
Plan hash value: 3374024865
------------------------------------------------------------------------------------------------------------
| Id  | Operation           | Name                 | Rows  | Bytes | Cost (%CPU)| Time     | Pstart| Pstop |
------------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT    |                      |       |       |    68 (100)|          |       |       |
|   1 |  PARTITION LIST ALL |                      |     1 |   247 |    68   (0)| 00:00:01 |     1 |     2 |
|   2 |   PARTITION LIST ALL|                      |     1 |   247 |    68   (0)| 00:00:01 |     1 |    20 |
|*  3 |    TABLE ACCESS FULL| GG_FUNCTION_LOCATION |     1 |   247 |    68   (0)| 00:00:01 |     1 |    40 |
------------------------------------------------------------------------------------------------------------

分析:我判断是解析这条SQL语句走错了执行计划,SELECT * FROM GG_function_location f WHERE f.parent_id ='03000000000001',于是我把改为

SELECT /*+gg*/* FROM GG_function_location f WHERE f.parent_id ='03000000000001',非常快。接近就简单了,把索引删除后,重建,会让此SQL重新解析。

解决方案:
drop index IDX_GG_FL_PARENT_ID;
create index IDX_GG_FL_PARENT_ID on GG_FUNCTION_LOCATION (PARENT_ID) nologging;

转载地址:http://jhdwo.baihongyu.com/

你可能感兴趣的文章
外部中断
查看>>
html的dtd声明
查看>>
ivy resolve标签
查看>>
.NET Web后台动态加载Css、JS 文件,换肤方案
查看>>
使用开源软件vlc media player 录制桌面视频
查看>>
web前端(2)—— 前端技术介绍
查看>>
ife2018 零基础学院 day 3
查看>>
__proto__和prototype
查看>>
Ibatis.Net 输出SQL语句学习(七)
查看>>
第一章-spring boot快速入门hello world
查看>>
《CLR Via C# 第3版》笔记之(十七) - 线程基础
查看>>
.NET MVC 找不到请求的 .Net Framework Data Provider。可能没有安装
查看>>
how to remove untagged / none images
查看>>
分析Redis架构设计
查看>>
linux scp远程拷贝文件及文件夹
查看>>
n个元素进栈,共有多少种出栈顺序?
查看>>
CodeForces 652C Foe Pairs
查看>>
HDU 1029 Ignatius and the Princess IV
查看>>
H5与Native交互之JSBridge技术
查看>>
干货!从Tomcat执行流程了解jsp是如何被解析的,错误提示是哪里生成的。
查看>>