Oracle一条SQL语句时快时慢

Wesley13
• 阅读 554

今天碰到一个非常奇怪的问题问题,一条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;

点赞
收藏
评论区
推荐文章
Jacquelyn38 Jacquelyn38
1年前
2020年前端实用代码段,为你的工作保驾护航
有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。 1、使用解构获取json数据let jsonData   id: 1, status: "OK", data: ['a', 'b'] ; let  id, status, data: number   jsonData; console.log(id, status, number )
blmius blmius
1年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录 问题 用navicat导入数据时,报错: 原因这是因为当前的MySQL不支持datetime为0的情况。 解决修改sql\mode: sql\mode:SQL Mode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。 全局s
由一次 UPDATE 过慢 SQL 优化而总结出的经验
最近,线上的 ETL 数据归档 SQL 发生了点问题,有一个 UPDATE SQL 跑了两天还没跑出来: update torderrecord set archiveid '420a7fe7476745e8a5f572280c192faa', updatetime updatetime where orderid in (select orderid
Wesley13 Wesley13
11个月前
asp.net中自动填充参数的存储过程类(C#)
执行一下这个sql: SELECT B.[name], C.[name] AS [type], B.length, B.isoutparam, B.isnullable FROM sysobjects AS A INNER JOIN"; syscolumns AS B ON A.id = B.id AND A.xtype = 'P'
Wesley13 Wesley13
11个月前
030 SSM综合练习06
**1.权限操作涉及的三张表** (1)用户表信息描述users ![](https://oscimg.oschina.net/oscnet/a4a2b1f943cbc2db1c8ddd613e7ed00a9ae.png) sql语句: CREATE TABLE users ( id VARCHAR2 ( 32 ) DEFAU
Wesley13 Wesley13
11个月前
MySQL查询按照指定规则排序
1.按照指定(单个)字段排序 select * from table_name order id desc; 2.按照指定(多个)字段排序 select * from table_name order id desc,status desc; 3.按照指定字段和规则排序 selec
Stella981 Stella981
11个月前
Django中Admin中的一些参数配置
### **设置在列表中显示的字段,id为django模型默认的主键** list_display = ('id', 'name', 'sex', 'profession', 'email', 'qq', 'phone', 'status', 'create_time') ### **设置在列表可编辑字段** list_editable
Wesley13 Wesley13
11个月前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
#### 背景描述 # Time: 2019-01-24T00:08:14.705724+08:00 # User@Host: **[**] @ [**] Id: ** # Schema: sentrymeta Last_errno: 0 Killed: 0 # Query_time: 0.315758 Lock_
Easter79 Easter79
11个月前
sql注入
反引号是个比较特别的字符,下面记录下怎么利用 0x00 SQL注入 ---------- 反引号可利用在分隔符及注释作用,不过使用范围只于表名、数据库名、字段名、起别名这些场景,下面具体说下 1)表名 payload:select \* from \`users\` where user\_id=1 limit 0,1; ![](https://o
helloworld_34035044 helloworld_34035044
2个月前
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。 uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid() 或 uuid(sep)参数说明:sep 布尔值,生成的uuid中是否包含分隔符'',缺省为