首页 数据库 mysql教程 SPA游标采集之去除重复

SPA游标采集之去除重复

Jun 07, 2016 pm 04:36 PM
spa 升级 去除 我们 数据库 游标 目的 采集 重复

当我们做数据库升级项目的时候,我们一般会去做性能回归测试,通俗一点来说,就是把10g生产库的语句拿到11g生产环境上运行,如果发现运行过程中,由于优化器、实例参数等改变导致执行计划变化,最终导致性能退化的语句,需要拿出来单独进行分析及验证。要做这

当我们做数据库升级项目的时候,我们一般会去做性能回归测试,通俗一点来说,就是把10g生产库的语句拿到11g生产环境上运行,如果发现运行过程中,由于优化器、实例参数等改变导致执行计划变化,最终导致性能退化的语句,需要拿出来单独进行分析及验证。要做这个事情,首先我们需要把我们的10g上的语句给采集出来,采集方法分为以下几种方式。

  • cursor cache
  • awr snapshots
  • awr baselines
  • another sql tuning set
  • 10046 trace file(11g+)

对于大型的生产库,我们一般采集的是方式是:游标还有awr snapshots的数据。为了能够完美的抓取到全部的SQL语句,我们往往需要一天对cursor cache进行多次采集。大部分建议是放在高峰期的时候采集,这么做主要是为了防止有些SQL还没被抓取到sqlset就从shared pool中purge出去了。在这个抓取的过程中,有一个困扰的问题就是literal sql的一些语句。举个例子如下:

select * from emp where empno=1456;
select * from emp where empno=1457;
select * from emp where empno=1458;

这三个SQL语句会先后被采集进来,每天都这样采集,会导致我们的SQLSET的结果集越来越大。正常情况下,一个大型的生产库的SQL语句也就几w条而已,但是如果你的硬解析非常多的话,可能在短短的几天,你采集的语句就会突破到100w条以上。然后在做后面SQLSET转换到中转表的这个过程,会执行相当长的时间,搞不好就报ORA-01555,导致运行一段时间后无法成功转换。我在这上面被坑了好几次。可能你会说,就100w的数据,Oracle应该很快转换出来的吧。这个我得解释一下。我们的中转表里面其实包含了好几个LOB字段和特殊TYPE类型。一旦数据量大了,可以说速度完全不行。正是基于这种原因,我们需要考虑一种方式,在采集的过程中进行去除重复的操作。

我们来举个例子说明下。

1.新建SQLSET

SQL> exec dbms_sqltune.CREATE_SQLSET('sqlset1'); 
PL/SQL procedure successfully completed.
SQL> select * from dba_sqlset; 
        ID NAME            OWNER           DESCRIPTION                    CREATED   LAST_MODI STATEMENT_COUNT 
---------- --------------- --------------- ------------------------------ --------- --------- --------------- 
         1 sqlset1         SYS                                            11-MAY-14 11-MAY-14               0
登录后复制

2.使用scott用户,执行几条语句,执行前先flush下shared pool

SQL> alter system flush shared_pool; 
System altered.
connect scott/tiger
select * from emp;
select * from emp where empno=1456;
select * from emp where empno=1457;
登录后复制

3.使用sys用户开始采集语句

DECLARE 
  mycur DBMS_SQLTUNE.SQLSET_CURSOR; 
BEGIN 
  OPEN mycur FOR 
    SELECT value(P) 
      FROM TABLE(dbms_sqltune.select_cursor_cache('parsing_schema_name in (''SCOTT'')', 
                                                  NULL, 
                                                  NULL, 
                                                  NULL, 
                                                  NULL, 
                                                  1, 
                                                  NULL, 
                                                  'ALL')) p; 
  dbms_sqltune.load_sqlset(sqlset_name     => 'sqlset1', 
                           populate_cursor => mycur, 
                           load_option     => 'MERGE'); 
  CLOSE mycur; 
END; 
/ 
SQL> select * from dba_sqlset; 
        ID NAME            OWNER           DESCRIPTION                    CREATED   LAST_MODI STATEMENT_COUNT 
---------- --------------- --------------- ------------------------------ --------- --------- --------------- 
         1 sqlset1         SYS                                            11-MAY-14 11-MAY-14               9
登录后复制

4.查看采集结果

SQL> select sql_id,sql_text from DBA_SQLSET_STATEMENTS ; 
SQL_ID        SQL_TEXT 
------------- -------------------------------------------------------------------------------- 
1srhq04p4x0zz SELECT /* OPT_DYN_SAMP */ /*+ ALL_ROWS IGNORE_WHERE_CLAUSE NO_PARALLEL(SAMPLESUB 
38mhtu5pc7d07 select * from emp where empno=1456 
7hys3h7ysgf9m SELECT ATTRIBUTE,SCOPE,NUMERIC_VALUE,CHAR_VALUE,DATE_VALUE FROM SYSTEM.PRODUCT_P 
a2dk8bdn0ujx7 select * from emp 
bc26hcc8td76f select * from emp where empno=1457 
cw6vxf0kbz3v1 SELECT CHAR_VALUE FROM SYSTEM.PRODUCT_PRIVS WHERE   (UPPER('SQL*Plus') LIKE UPPE 
d6vwqbw6r2ffk SELECT USER FROM DUAL 
dyk4dprp70d74 SELECT DECODE('A','A','1','2') FROM DUAL 
g4y6nw3tts7cc BEGIN DBMS_APPLICATION_INFO.SET_MODULE(:1,NULL); END;
登录后复制

从这里我们可以观察到我们的三条语句都采集进来了。这里我们可以看到我们的literal sql,如果每天对游标采集好几次的话,我们的literal sql会越采集越多,导致SQLSET的结果集非常大。当SQL数量达到百万级别后,使得我们的转换非常慢。如何去重呢?我们看下这个DBA_SQLSET_STATEMENTS的结构。

SQL> desc DBA_SQLSET_STATEMENTS 
Name                                        Null?    Type 
------------------------------------------- -------- ----------------------------- 
SQLSET_NAME                                 NOT NULL VARCHAR2(30) 
SQLSET_OWNER                                         VARCHAR2(30) 
SQLSET_ID                                   NOT NULL NUMBER 
SQL_ID                                      NOT NULL VARCHAR2(13) 
FORCE_MATCHING_SIGNATURE                    NOT NULL NUMBER 
SQL_TEXT                                             CLOB 
PARSING_SCHEMA_NAME                                  VARCHAR2(30) 
PARSING_SCHEMA_ID                                    NUMBER 
PLAN_HASH_VALUE                             NOT NULL NUMBER 
BIND_DATA                                            RAW(2000) 
BINDS_CAPTURED                                       CHAR(1) 
MODULE                                               VARCHAR2(64) 
ACTION                                               VARCHAR2(64) 
ELAPSED_TIME                                         NUMBER 
CPU_TIME                                             NUMBER 
BUFFER_GETS                                          NUMBER 
DISK_READS                                           NUMBER 
DIRECT_WRITES                                        NUMBER 
ROWS_PROCESSED                                       NUMBER 
FETCHES                                              NUMBER 
EXECUTIONS                                           NUMBER 
END_OF_FETCH_COUNT                                   NUMBER 
OPTIMIZER_COST                                       NUMBER 
OPTIMIZER_ENV                                        RAW(2000) 
PRIORITY                                             NUMBER 
COMMAND_TYPE                                         NUMBER 
FIRST_LOAD_TIME                                      VARCHAR2(19) 
STAT_PERIOD                                          NUMBER 
ACTIVE_STAT_PERIOD                                   NUMBER 
OTHER                                                CLOB 
PLAN_TIMESTAMP                                       DATE 
SQL_SEQ                                     NOT NULL NUMBER
SQL> select sql_id,sql_text,FORCE_MATCHING_SIGNATURE from DBA_SQLSET_STATEMENTS; 
SQL_ID        SQL_TEXT                                                                            FORCE_MATCHING_SIGNATURE 
------------- -------------------------------------------------------------------------------- --------------------------- 
1srhq04p4x0zz SELECT /* OPT_DYN_SAMP */ /*+ ALL_ROWS IGNORE_WHERE_CLAUSE NO_PARALLEL(SAMPLESUB         4094562552765466770 
38mhtu5pc7d07 select * from emp where empno=1456                                                      16946033956547040230 
7hys3h7ysgf9m SELECT ATTRIBUTE,SCOPE,NUMERIC_VALUE,CHAR_VALUE,DATE_VALUE FROM SYSTEM.PRODUCT_P        10967007256268736959 
a2dk8bdn0ujx7 select * from emp                                                                        7001777653489406494 
bc26hcc8td76f select * from emp where empno=1457                                                      16946033956547040230 
cw6vxf0kbz3v1 SELECT CHAR_VALUE FROM SYSTEM.PRODUCT_PRIVS WHERE   (UPPER('SQL*Plus') LIKE UPPE        18201431879876406267 
d6vwqbw6r2ffk SELECT USER FROM DUAL                                                                   17376422952071979402 
dyk4dprp70d74 SELECT DECODE('A','A','1','2') FROM DUAL                                                 1846728577492307645 
g4y6nw3tts7cc BEGIN DBMS_APPLICATION_INFO.SET_MODULE(:1,NULL); END;                                   0
登录后复制

这里我们主要利用FORCE_MATCHING_SIGNATURE这个字段。可以看到我们的literal sql的FORCE_MATCHING_SIGNATURE的值是相同的。这里是16946033956547040230。所以我们要对这个列进行distinct,并将distinct出来的值放在一个我们自定义的Table里面。

5.去重采集

SQL> create table spaqc as select distinct FORCE_MATCHING_SIGNATURE from DBA_SQLSET_STATEMENTS; 
Table created. 
SQL> select * from spaqc; 
   FORCE_MATCHING_SIGNATURE 
--------------------------- 
       18201431879876406267 
        1846728577492307645 
        4094562552765466770 
       17376422952071979402 
       10967007256268736959 
        7001777653489406494 
       16946033956547040230 
                          0 
8 rows selected.
登录后复制

这里需要注意一下FORCE_MATCHING_SIGNATURE为0的情况下,一般是运行PL/SQL、JOB之类的操作,这个我们不能过滤掉。所以我们要把0这行给删掉。

SQL> delete from spaqc where FORCE_MATCHING_SIGNATURE=0; 
1 row deleted. 
SQL> commit; 
Commit complete.
登录后复制

6.再次测试,看看literal sql会不会被采集。

select * from emp where empno=1458;
select * from emp where empno=1459;
select * from emp where empno=1460;
select * from emp where empno=1460 and ENAME='scott';
DECLARE 
  mycur DBMS_SQLTUNE.SQLSET_CURSOR; 
BEGIN 
  OPEN mycur FOR 
    SELECT value(P) 
      FROM TABLE(dbms_sqltune.select_cursor_cache('parsing_schema_name in (''SCOTT'') and FORCE_MATCHING_SIGNATURE not in (select FORCE_MATCHING_SIGNATURE from spaqc)', 
                                                  NULL, 
                                                  NULL, 
                                                  NULL, 
                                                  NULL, 
                                                  1, 
                                                  NULL, 
                                                  'ALL')) p; 
  dbms_sqltune.load_sqlset(sqlset_name     => 'sqlset1', 
                           populate_cursor => mycur, 
                           load_option     => 'MERGE'); 
  CLOSE mycur; 
END; 
/ 
SQL> select sql_id,sql_text,FORCE_MATCHING_SIGNATURE from DBA_SQLSET_STATEMENTS ; 
SQL_ID        SQL_TEXT                                                                            FORCE_MATCHING_SIGNATURE 
------------- -------------------------------------------------------------------------------- --------------------------- 
1srhq04p4x0zz SELECT /* OPT_DYN_SAMP */ /*+ ALL_ROWS IGNORE_WHERE_CLAUSE NO_PARALLEL(SAMPLESUB         4094562552765466770 
38mhtu5pc7d07 select * from emp where empno=1456                                                      16946033956547040230 
7hys3h7ysgf9m SELECT ATTRIBUTE,SCOPE,NUMERIC_VALUE,CHAR_VALUE,DATE_VALUE FROM SYSTEM.PRODUCT_P        10967007256268736959 
a2dk8bdn0ujx7 select * from emp                                                                        7001777653489406494 
bc26hcc8td76f select * from emp where empno=1457                                                      16946033956547040230 
cw6vxf0kbz3v1 SELECT CHAR_VALUE FROM SYSTEM.PRODUCT_PRIVS WHERE   (UPPER('SQL*Plus') LIKE UPPE        18201431879876406267 
d6vwqbw6r2ffk SELECT USER FROM DUAL                                                                   17376422952071979402 
d8fw5smyjva0b select * from emp where empno=1460 and ENAME='scott'                                    17445701640293030006 
dyk4dprp70d74 SELECT DECODE('A','A','1','2') FROM DUAL                                                 1846728577492307645 
g4y6nw3tts7cc BEGIN DBMS_APPLICATION_INFO.SET_MODULE(:1,NULL); END;                                                      0 
10 rows selected.
登录后复制

这里我们看到literal sql没有被采集进来,我们实现了游标采集的过滤。

本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

Video Face Swap

Video Face Swap

使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热工具

记事本++7.3.1

记事本++7.3.1

好用且免费的代码编辑器

SublimeText3汉化版

SublimeText3汉化版

中文版,非常好用

禅工作室 13.0.1

禅工作室 13.0.1

功能强大的PHP集成开发环境

Dreamweaver CS6

Dreamweaver CS6

视觉化网页开发工具

SublimeText3 Mac版

SublimeText3 Mac版

神级代码编辑软件(SublimeText3)

热门话题

Java教程
1657
14
CakePHP 教程
1415
52
Laravel 教程
1309
25
PHP教程
1257
29
C# 教程
1231
24
小艺升级为智能体!HarmonyOS NEXT鸿蒙原生智能开启全新AI时代 小艺升级为智能体!HarmonyOS NEXT鸿蒙原生智能开启全新AI时代 Jun 22, 2024 am 01:56 AM

6月21日,华为开发者大会2024(HDC2024)再聚东莞松山湖。本届大会上,最令人关注的莫过于HarmonyOSNEXT正式面向开发者和先锋用户启动Beta,并全方位展示了HarmonyOSNEXT全场景、原生智能和原生安全三大“王炸”级创新特性。HarmonyOSNEXT原生智能:开启全新AI时代放弃安卓框架之后,HarmonyOSNEXT成为真正独立于安卓、iOS的操作系统,堪称是一场史无前例的脱胎换骨。在其众多新特性中,原生智能无疑是最能带给用户直观感受和体验升级的新特性

iOS 18 新增'已恢复”相册功能 可找回丢失或损坏的照片 iOS 18 新增'已恢复”相册功能 可找回丢失或损坏的照片 Jul 18, 2024 am 05:48 AM

苹果公司最新发布的iOS18、iPadOS18以及macOSSequoia系统为Photos应用增添了一项重要功能,旨在帮助用户轻松恢复因各种原因丢失或损坏的照片和视频。这项新功能在Photos应用的"工具"部分引入了一个名为"已恢复"的相册,当用户设备中存在未纳入其照片库的图片或视频时,该相册将自动显示。"已恢复"相册的出现为因数据库损坏、相机应用未正确保存至照片库或第三方应用管理照片库时照片和视频丢失提供了解决方案。用户只需简单几步

华为 Mate 60 系列最佳入手时机,新增 AI 消除 + 影像升级,更可享秋日礼遇活动 华为 Mate 60 系列最佳入手时机,新增 AI 消除 + 影像升级,更可享秋日礼遇活动 Aug 29, 2024 pm 03:33 PM

自去年华为Mate60系列开售以来,我个人就一直将Mate60Pro作为主力机使用。在将近一年的时间里,华为Mate60Pro经过多次OTA升级,综合体验有了显着提升,给人一种常用常新的感觉。比如近期,华为Mate60系列就再度迎来了影像功能的重磅升级。首先是新增AI消除功能,可以智能消除路人、杂物并对空白部分进行自动补充;其次是主摄色准、长焦清晰度均有明显升级。考虑到现在是开学季,华为Mate60系列还推出了秋日礼遇活动:购机可享至高800元优惠,入手价低至4999元。常用常新的产品力加上超值

在PHP中使用MySQLi建立数据库连接的详尽教程 在PHP中使用MySQLi建立数据库连接的详尽教程 Jun 04, 2024 pm 01:42 PM

如何在PHP中使用MySQLi建立数据库连接:包含MySQLi扩展(require_once)创建连接函数(functionconnect_to_db)调用连接函数($conn=connect_to_db())执行查询($result=$conn->query())关闭连接($conn->close())

iCloud存储已满通知:如何修复 iCloud存储已满通知:如何修复 Apr 24, 2024 pm 04:43 PM

每当您下载某些文件或空投某些内容时,您的iPhone是否显示“iCloud存储空间已满”?iCloud储存空间的免费套餐限制为仅5GB。因此,您应该检查的第一件事是手机上iCloud的当前存储情况。如果仍有足够的存储空间,并且您收到通知,则这些解决方案将帮助您进行故障排除。修复1–删除iCloud备份从手机设置中移除现有版本的iCloud备份。步骤1–打开设置。步骤2–您将在“设置”面板的顶部找到您的AppleID。点击它以打开它。步骤3–打开“iCloud”以打开iCloud设置。步骤4–向下

如何在PHP中处理数据库连接错误 如何在PHP中处理数据库连接错误 Jun 05, 2024 pm 02:16 PM

PHP中处理数据库连接报错,可以使用以下步骤:使用mysqli_connect_errno()获取错误代码。使用mysqli_connect_error()获取错误消息。通过捕获并记录这些错误信息,可以轻松识别并解决数据库连接问题,确保应用程序的顺畅运行。

如何在 Golang 中使用数据库回调函数? 如何在 Golang 中使用数据库回调函数? Jun 03, 2024 pm 02:20 PM

在Golang中使用数据库回调函数可以实现:在指定数据库操作完成后执行自定义代码。通过单独的函数添加自定义行为,无需编写额外代码。回调函数可用于插入、更新、删除和查询操作。必须使用sql.Exec、sql.QueryRow或sql.Query函数才能使用回调函数。

如何用 Golang 连接远程数据库? 如何用 Golang 连接远程数据库? Jun 01, 2024 pm 08:31 PM

通过Go标准库database/sql包,可以连接到MySQL、PostgreSQL或SQLite等远程数据库:创建包含数据库连接信息的连接字符串。使用sql.Open()函数打开数据库连接。执行SQL查询和插入操作等数据库操作。使用defer关闭数据库连接以释放资源。

See all articles