返回顶部
首页 > 资讯 > 数据库 >SQL Profile(第二篇)
  • 470
分享到

SQL Profile(第二篇)

2024-04-02 19:04:59 470人浏览 安东尼
摘要

通过sql Tuning Advisor使用SQL profile 在11GR2上SQL Tuning Advisor已经变得非常好用,我非常喜欢将一些非常复杂的SQL语句交给SQL Tunin

通过sql Tuning Advisor使用SQL profile

在11GR2上SQL Tuning Advisor已经变得非常好用,我非常喜欢将一些非常复杂的SQL语句交给SQL Tuning Advisor来调优,几乎每次都不让我失望,通常调优结束后,SQL Tuning Advisor都会给你一些建议,例如建议你创建索引或者收集统计信息,或者建议你接受SQL Profile并且给出了接受SQL Profile后性能将得到的提升。本节将会给出一个示例来演示如何通过SQL Tuning Advisor来使用SQL Profile。首先我们需要构建一下需要用到的测试表:

SQL>CREATE TABLE test

  2   AS

  3   SELECT ROWNUM id,

  4          DBMS_RANDOM.STRING('A', 12) name,

  5          DECODE(MOD(ROWNUM, 500), 0, 'Inactive', 'Active') status

  6     FROM all_objects a,dba_objects b

  7    WHERE ROWNUM <= 50000;

 

Table created.

 

SQL>create index t_ind on t(status);

 

Index created.

 

SQL>begin

  2     dbms_stats.gather_table_stats(ownname          =>'test',

  3                                   tabname          => 'test',

  4                                   no_invalidate    => FALSE,

  5                                   estimate_percent => 100,

  6                                   force            => true,

  7                                   degree         => 5,

  8                              method_opt       => 'for all columns  size 1',

  9                                   cascade          => true);

 10   end;

 11   /

 

SQL>select status,count(*) from test group by status;

 

STATUS             COUNT(*)

---------------- ----------

Active                49900

Inactive                100

 

上面的代码做了下面几件事:

l 创建了一张测试表test,总记录数50000。

l 表上的字段status一共有2个唯一值:Active和Inactive,此字段有数据倾斜。

l 列status上值为Active的值有49900个,占了表里绝大多数的记录,为Inactive的记录非常少,只有100个。

l status字段上有索引,分析了表的统计信息,但是status字段没有收集直方图。

我们来对status为Inactive的值做查询,由于status为Inactive的值非常少,因此走索引扫描性能更好,但是由于列上缺少直方图,因此执行计划会走全表扫描:

SQL>select count(name) from test where status='Inactive';

 

COUNT(NAME)

-----------

        100

 

SQL>select * from table(dbms_xplan.display_cursor);

PLAN_TABLE_OUTPUT

------------------------------------------------------------------------------

SQL_ID  c37q7z5qjnwwf, child number 0

-------------------------------------

select count(name) from test where status='Inactive'

Plan hash value: 1950795681

---------------------------------------------------------------------------

| Id  | Operation          | Name | Rows  | Bytes | Cost (%CPU)| Time     |

---------------------------------------------------------------------------

|   0 | SELECT STATEMENT   |      |       |       |    51 (100)|          |

|   1 |  SORT AGGREGATE    |      |     1 |    21 |            |          |

|*  2 |   TABLE ACCESS FULL| TEST | 25000 |   512K|    51   (2)| 00:00:01 |

---------------------------------------------------------------------------

上面执行计划里显示的经过谓词过滤后的全表扫描返回的基数为25000,因为缺少直方图,因此优化器就简单的通过 基数=表的总记录数/status字段的唯一值数量=50000/2=25000来得出基数。我们来通过SQL Tuning Advisor分析一下这个SQL,看看优化器能不能识别到这是一个低效的执行计划,能否给出我们一些建议:

SQL>var c varchar2(100)

SQL>exec :c := dbms_sqltune.CREATE_TUNING_TASK(SQL_ID=>'c37q7z5qjnwwf')

 

PL/SQL procedure successfully completed.

 

SQL>exec dbms_sqltune.execute_tuning_task(task_name => :c)

 

PL/SQL procedure successfully completed.

 

SQL>select dbms_sqltune.report_tuning_task(:c) from dual;

 

DBMS_SQLTUNE.REPORT_TUNING_TASK(:C)

-------------------------------------------------------------------------------

GENERAL INFORMATION SECTION

-------------------------------------------------------------------------------

Tuning Task Name   : TASK_1112

Tuning Task Owner  : TEST

Workload Type      : Single SQL Statement

Scope              : COMPREHENSIVE

Time Limit(seconds): 1800

Completion Status  : COMPLETED

Started at         : 08/01/2014 15:59:32

Completed at       : 08/01/2014 15:59:33

-------------------------------------------------------------------------------

Schema Name: TEST

SQL ID     : c37q7z5qjnwwf

SQL Text   : select count(name) from test where status='Inactive'

-------------------------------------------------------------------------------

FINDINGS SECTION (1 finding)

-------------------------------------------------------------------------------

1- SQL Profile Finding (see explain plans section below)

--------------------------------------------------------

  A potentially better execution plan was found for this statement.

  Recommendation (estimated benefit: 51.46%)

  ------------------------------------------

  - Consider accepting the recommended SQL Profile.

    execute dbms_sqltune.accept_sql_profile(task_name => 'TASK_1112',

            task_owner => 'TEST', replace => TRUE);

 

  Validation results

  ------------------

  The SQL Profile was tested by executing both its plan and the original plan

  and measuring their respective execution statistics. A plan may have been

  only partially executed if the other could be run to completion in less time.

 

                           Original Plan  With SQL Profile  % Improved

                           -------------  ----------------  ----------

  Completion Status:            COMPLETE          COMPLETE

  Elapsed Time (s):              .00212           .000221      89.57 %

  CPU Time (s):                 .002099             .0002      90.47 %

  User I/O Time (s):                  0                 0

  Buffer Gets:                      210               102      51.42 %

  Physical Read Requests:             0                 0

  Physical Write Requests:            0                 0

  Physical Read Bytes:                0                 0

  Physical Write Bytes:               0                 0

  Rows Processed:                     1                 1

  Fetches:                            1                 1

  Executions:                         1                 1

 

  Notes

  -----

  1. Statistics for the original plan were averaged over 10 executions.

  2. Statistics for the SQL Profile plan were averaged over 10 executions.

-------------------------------------------------------------------------------

EXPLAIN PLANS SECTION

-------------------------------------------------------------------------------

1- Original With Adjusted Cost

------------------------------

Plan hash value: 1950795681

---------------------------------------------------------------------------

| Id  | Operation          | Name | Rows  | Bytes | Cost (%CPU)| Time     |

---------------------------------------------------------------------------

|   0 | SELECT STATEMENT   |      |     1 |    21 |    51   (2)| 00:00:01 |

|   1 |  SORT AGGREGATE    |      |     1 |    21 |            |          |

|*  2 |   TABLE ACCESS FULL| TEST |   100 |  2100 |    51   (2)| 00:00:01 |

---------------------------------------------------------------------------

2- Using SQL Profile

--------------------

Plan hash value: 4130896540

--------------------------------------------------------------------------------------

| Id  | Operation                    | Name  | Rows  | Bytes | Cost (%CPU)| Time     |

--------------------------------------------------------------------------------------

|   0 | SELECT STATEMENT             |       |     1 |    21 |     2   (0)| 00:00:01 |

|   1 |  SORT AGGREGATE              |       |     1 |    21 |            |          |

|   2 |   TABLE ACCESS BY INDEX ROWID| TEST  |   100 |  2100 |     2   (0)| 00:00:01 |

|*  3 |    INDEX RANGE SCAN          | T_IND |   100 |       |     1   (0)| 00:00:01 |

--------------------------------------------------------------------------------------

Dbms_sqltune包被用来创建调优任务、执行调优任务、查看调优结果,通过dbms_sqltune包的CREATE_TUNING_TASK函数来为SQL_ID为c37q7z5qjnwwf的SQL创建了一个调优任务。然后通过execute_tuning_task过程来执行这个调优任务,任务运行后,优化器会利用动态采样等技术去验证评估内容与实际内容的差异,并且根据差异去调整执行计划。最后通过report_tuning_task来产生report查看调优的结果。调优结果里为我们提供了一个建议,建议我们采用一个SQL Profile,并且比对了采用SQL Profile后的性能提升,report的后面EXPLAIN PLANS SECTION部分展示了采用SQL Profile后,执行计划变为了索引扫描,而且基数的评估非常准确,从25000已经变为了100。

Note:当你运行SQL Tuning Advisor后,建议你接受一个SQL Profile,如果你想在接受SQL Profile前知道它到底为你提供了些什么,可以运行以下查询获得:

sys@DLSP>select                                              

  2   --    b.ATTR1        -- 10g 列     

  3         b.ATTR5        -- 11g 列     

  4   from                               

  5           wri$_adv_tasks     a,      

  6           wri$_adv_rationale b       

  7   where                              

  8           a.name = 'TASK_1112'       

  9   and     b.task_id = a.id           

 10   order by                           

 11           b.rec_id, b.id             

 12   ;                   

 

ATTR5

---------------------------------------------------------------------------

OPT_ESTIMATE(@"SEL$1", TABLE, "TEST"@"SEL$1", SCALE_ROWS=0.004)

OPT_ESTIMATE(@"SEL$1", INDEX_SCAN, "TEST"@"SEL$1", "T_IND", SCALE_ROWS=0.004)

OPTIMIZER_FEATURES_ENABLE(default)

 

wri$_adv_tasks的name字段为任务名,在我们上面的例子里,可以通过print c在SQLPLUS环境下获得任务名,也可以在dbms_sqltune.report_tuning_task(:c)的输出里找到任务名。

我们接受这个SQL Profile来看看再次查询是否能用到刚创建的SQL Profile:

SQL>execute dbms_sqltune.accept_sql_profile(task_name => 'TASK_1112',-

>             task_owner => 'TEST', replace => TRUE);

 

PL/SQL procedure successfully completed.

 

SQL>select count(name) from test where status='Inactive';

 

COUNT(NAME)

-----------

        100

 

SQL>select * from table(dbms_xplan.display_cursor);

 

PLAN_TABLE_OUTPUT

------------------------------------------------------------------------------

SQL_ID  c37q7z5qjnwwf, child number 0

-------------------------------------

select count(name) from test where status='Inactive'

 

Plan hash value: 4130896540

--------------------------------------------------------------------------------------

| Id  | Operation                    | Name  | Rows  | Bytes | Cost (%CPU)| Time     |

--------------------------------------------------------------------------------------

|   0 | SELECT STATEMENT             |       |       |       |     2 (100)|          |

|   1 |  SORT AGGREGATE              |       |     1 |    21 |            |          |

|   2 |   TABLE ACCESS BY INDEX ROWID| TEST  |   100 |  2100 |     2   (0)| 00:00:01 |

|*  3 |    INDEX RANGE SCAN          | T_IND |   100 |       |     1   (0)| 00:00:01 |

--------------------------------------------------------------------------------------

Note

-----

   - SQL Profile SYS_SQLPROF_01479094feeb0003 used for this statement

 

接受SQL Tuning Advisor提供的SQL Profile后,执行计划Note部分:- SQL Profile SYS_SQLPROF_01479094feeb0003 used for this statement,显示已经使用到了SQL Profile,注意由SQL Tuning Advisor产生的SQL Profile名称都是SYS_SQLPROF作为前缀,使用到SQL Profile后执行计划也已经从全表扫描变为了索引扫描。dbms_sqltune的accept_sql_profile过程有多个参数可用,task_name、task_owner指创建SQL调优任务的任务名和所属用户,参数name和DESCRIPTION指SQL Profile的名字和对SQL Profile的描述,参数CATEGoRY来指定创建的SQL Profile所属的类,默认的类为default。参数replace代表是否取代已有的SQL Profile,由于一个SQL只能有一个SQL Profile,不像Baseline,一个SQL可用有多个Baseline,因此如果一个SQL已经存在了SQL Profile,那么重新创建时,必须指定replace参数,设置为true,参数force_match指明了文本标准化的方式,默认为false。一旦接受SQL Profile,就可以通过视图dba_sql_profiles视图来查看SQL Profile的相关信息。因为SQL Profile并不属于某个用户,因此all_sql_profiles和user_sql_profiles视图都不可用。

如果一个SQL使用了SQL Profile,那么这个SQL的v$sql的sql_profile字段会显示使用到的SQL Profile的名字。下面的查询显示了系统中存在的SQL Profile和当前共享池中正在使用的SQL Profile的SQL。

SQL>select name, category, status, substr(sql_text,1,25) sql_text, force_matching

  2  from dba_sql_profiles

  3  where sql_text like nvl('&sql_text','%')

  4  and name like nvl('&name',name)

  5  order by last_modified

  6  ;

Enter value for sql_text:

Enter value for name:

 

NAME                           CATEGORY  STATUS   SQL_TEXT                   FORCE_

------------------------------ --------- -------- -------------------------  ------

profile_c99yw1xkb4f1u_dwrose   DEFAULT   ENABLED  select * from test         NO

profile_bhm28h6575bjy_dwrose   DEFAULT   ENABLED  select test2.object_name,  NO

profile_51k1ug4rwah3c_dwrose   DEFAULT   ENABLED  select distinct substr(ma  NO

profile_cm6stbx539mcz_dwrose   DEFAULT   ENABLED  select count(*) from tt    NO

profile_c37q7z5qjnwwf_dwrose   DEFAULT   ENABLED  select count(name) from t  NO

 

SQL>select sql_id,

  2         child_number cn,

  3         plan_hash_value plan_hash,

  4         sql_profile,

  5         executions execs,

  6         buffer_gets / decode(nvl(executions, 0), 0, 1, executions) avg_lio

  7    from v$sql s

  8   where upper(sql_text) like upper(nvl('&sql_text', sql_text))

  9     and sql_text not like '%from v$sql where sql_text like nvl(%'

 10     and sql_id like nvl('&sql_id', sql_id)

 11     and sql_profile is not null

 12   order by 1, 2, 3 ;

Enter value for sql_text:

 

SQL_ID          CN  PLAN_HASH SQL_PROFILE                    EXECS    AVG_LIO

-------------- --- ---------- ------------------------------ ----- ----------

c37q7z5qjnwwf    0 4130896540 profile_c37q7z5qjnwwf_dwrose       1        108

c37q7z5qjnwwf    1 4130896540 profile_c37q7z5qjnwwf_dwrose       2        105

我们根据SQL_PROFILE的命名知道,这些SQL Profile都不是SQL Tuning Advisor创建的,是我们手工创建的,因为SQL Tuning Advisor创建的SQL Profile都是以SYS_SQLPROF作为前缀的。

您可能感兴趣的文档:

--结束END--

本文标题: SQL Profile(第二篇)

本文链接: https://lsjlt.com/news/46310.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • SQL Profile(第二篇)
    通过SQL Tuning Advisor使用SQL profile 在11GR2上SQL Tuning Advisor已经变得非常好用,我非常喜欢将一些非常复杂的SQL语句交给SQL Tunin...
    99+
    2024-04-02
  • 第二篇:ssh.invoke_shell
    接上一篇:按照上一篇的方式,在没有对ssh.invoke_shell()执行后的登录提示符进行判断的话,那边有部分机器就回因为返回为空导致程序卡死。 正常机器  ssh.recv(9999)  命令返回内容: b'Last login: ...
    99+
    2023-01-30
    第二篇 ssh invoke_shell
  • Adaptive Cursor Sharing(第二篇)
    选择率和硬解析 我们上面提到了,在v$sql_cs_histogram视图中,如果此游标的3个桶中出现了两个桶中的count都有非0值,那么此后的解析都要窥探绑定变量的值计算谓词选择率,如果计算选...
    99+
    2024-04-02
  • robotFramework第二篇之关键
    lesson.robot 1 *** Keywords *** 2 打开谷歌浏览器并访问百度首页 3 Log 打开浏览器,输入http://www.baidu.com,进入百度首页 4 5 输入用户名 6 ...
    99+
    2023-01-30
    第二篇 关键 robotFramework
  • 【Python之旅】第四篇(二):Pyt
        在Python程序的执行过程中,难免会出现异常的情况,如果做的是跟用户交互的程序,当用户输入不可接受的内容时,在可预见的范围内,我们当然是希望可以给用户一些提示,而不是原来Python内置异常中的那些提示语句,毕竟那些语句只适合给程...
    99+
    2023-01-31
    之旅 第四篇 Python
  • 【Python之旅】第二篇(一):Pyt
    说明:    主要是file()和open()函数的使用,但在查open()函数的帮助时,会有下面的说明:>>> help(open) …… Open a file using the file() type, retur...
    99+
    2023-01-31
    之旅 第二篇 Python
  • 【Python之旅】第五篇(二):Pyt
        前面第五篇(一)中的一个Socket例子其实就是单线程的,即Server端一次只能接受来自一个Client端的连接,为了更好的说明socket单线程和阻塞模式,下面对前面的例子做修改。1.单线程+阻塞+交互式    前面的例子是单线...
    99+
    2023-01-31
    之旅 第五篇 Python
  • Python 学习日记第二篇 -- 列表
    一、列表    列表是一个可以包含所有数据类型的对象的位置有序集合,它是可以改变的。   1、列表的序列操作(Python3)>>> one_list = [1,2,3,4] >>> two_list =...
    99+
    2023-01-31
    第二篇 日记 列表
  • Java面试题冲刺第二天--Redis篇
    目录面试题1:为什么要用 Redis ?业务在哪块儿用到的?正经回答:深入追问: 追问1:Redis里有哪些数据类型?追问2:Redis与Memcached有哪些区别?追问3:那Re...
    99+
    2024-04-02
  • 怎么是SQL Profile
    本篇内容主要讲解“怎么是SQL Profile”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“怎么是SQL Profile”吧!SQL Profile是什么 ...
    99+
    2024-04-02
  • 【MySQL从删库到跑路 | 基础第二篇】——谈谈SQL中的DML语句
    个人主页:兜里有颗棉花糖 欢迎 点赞👍 收藏✨ 留言✉ 加关注💓本文由 兜里有颗棉花糖 原创 收录于专栏【MySQL学习专栏】🎈 本专栏旨在分享学习...
    99+
    2023-09-16
    mysql sql 数据库
  • Python成长之路第二篇(3)_字典的
    字典的置函数用法(字典dict字典中的key不可以重复)class dict(object):"""dict() -> new empty dictionarydict(mapping) -> new dictionary in...
    99+
    2023-01-31
    字典 第二篇 成长之路
  • 第十二篇 1+X考证 Web前端测试题PHP篇(新)
     单选题  1、以下关于PHP面向对象的说法错误的是( A ) A、PHP可以多重继承,一个类可以继承多个父类 B、PHP使用new运算符来获取一个实例对象 C、一个类可以在声明中用extends关键字继承另一个类的方法和属性 D、...
    99+
    2023-09-06
    php 开发语言 前端
  • Manual类型的SQL Profile
    实验目的:Manual类型稳定执行计划,相对AUTOMATIC类型更稳定 关键词: dbms_stats.gather_table_stats、 DBMS_SQLTUNE.DROP...
    99+
    2024-04-02
  • Java基础第二篇方法与数据成员
    目录1、调用同一对象的数据成员2、方法的参数列表3、调用同一对象的其他方法4、数据成员初始化5、总结上一篇文章Java基础 从HelloWorld到面向对象 1、调用同一对象的数据成...
    99+
    2024-04-02
  • SQL实现LeetCode(176.第二高薪水)
    [LeetCode] 176.Second Highest Salary 第二高薪水 Write a SQL query to get the second highest sala...
    99+
    2024-04-02
  • openCV第一篇
    文章目录 前言:计算机眼中的图片  1. 图片的读取与显示 1.1 图片的读取  1.2 显示的图片 1.2.1 显示原始图片  1.2.2 灰度图 1.3 BGR转换成灰度图、RGB 2. 保存图片 3. 视频的读取与显示 4. 截取图像...
    99+
    2023-09-11
    opencv 计算机视觉 python
  • 第七篇:suds.TypeNotFoun
    想要用Python的suds模块调用webservice地址做自动测试,但是找了很多方法都失败了,最终找到另外一个模块可以作为客户端访问服务器地址。 1.针对非安全的http from zeep import Client url = "...
    99+
    2023-01-30
    第七篇 suds TypeNotFoun
  • 第一篇python
    1、CentOS Linux release 7.2.1511 (Core) 升级python2.7.5到3.6.12、wget https://www.python.org/ftp/python/3.6.1/Python-3.6.1.tg...
    99+
    2023-01-31
    第一篇 python
  • 如何手工创建SQL Profile
    本篇内容介绍了“如何手工创建SQL Profile”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!手工创建S...
    99+
    2024-04-02
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作