扫二维码与项目经理沟通
我们在微信上24小时期待你的声音
解答本文疑问/技术咨询/运营咨询/技术建议/互联网交流
LoadRunner 9.0
创新互联公司专注于邵东网站建设服务及定制,我们拥有丰富的企业做网站经验。 热诚为您提供邵东营销型网站建设,邵东网站制作、邵东网页设计、邵东网站官网定制、微信平台小程序开发服务,打造邵东网络公司原创品牌,更为您提供邵东网站排名全网营销落地服务。
Sitescope 9.0
Windows 2003
Oracle database 10g
1. 使用LR自带的监控引擎
1.1.在LR的controller上安装oracle客户端
这一步就不用说了,安装直接Setup,安装就OK了。
1,安装完后,先配置一下Net Configuration Assistant。记住配置的服务名。
配置成功会显示:正在连接...测试成功。
2,用sqlplus连接一下,看是否可以连接成功,打开sqlplus输入oracle用户名密码和主机字符串。
查看是否登录成功。
1.2.添加oracle计数器
3,登录成功后,打开LR的controller.,在可用图中选择oracle,点击add measurements,再点击Advanced,如下所示:
这里我们用LR native monitors。
4,在Monitored Server Machines区域,添加oracle服务器所在的IP。
5,再在Resource Measurements on:IP区域点击添加,弹出对话框如下:
6,输入相应的信息,这里的orcl就是前面在Net Configuration Assistant配置的服务名。
7,点击OK,这里我们应该可以看到可以添加oracle的计数器了,如下所示:
2. 使用Sitescope引擎
不需要配置Net Configuration Assistant。
1,在第一个图choose monitor engine中选择sitescope,然后在在Monitored Server Machines区域点击Add如下所示:
在这里可以选择本地或者其他机器的sitescope,如果sitescope启用了aclearcase/" target="_blank" ccount的验证,也要写上相应的用户名密码。
2,在Resource Measurements on:IP区域点击添加,弹出对话框如下:
3,输入信息如图。点击OK,如下:
至此就可以监控oracle了。
在数据库管理与维护中,我们总会遇到一个问题:我们创建的索引是否会被某些SQL语句使用呢?换个通俗表达方式:我创建的索引是否是未使用的索引(unused Indexes),是否有价值呢?如果创建的某个索引是Unused Indexes,尤其是没有合理规划索引的系统或那些管理控制不规范的系统。有可能建立了N个索引,其实有些索引都是没有任何SQL会使用,那么此时这些多余的索引其实会带来两个问题:1:浪费存储空间,尤其是大表的索引,浪费的存储空间尤其可观; 2:加重DML操作(UPDATE、INSERT、DELETE)的开销。
ORACLE其实提供了监控索引使用情况的功能。ALTER INDEX index_name MONITORING USAGE; 我们下面来测试验证一下吧。
创建一个表TEST作为实验测试验证的样例
CREATE TABLE TEST
(
ID NUMBER(10),
NAME VARCHAR2(32)
);
CREATE INDEX IDX_TEST_ID ON TEST(ID);
INSERT INTO TEST
SELECT 1001, 'Kerry' FROM DUAL UNION ALL
SELECT 1002, 'Ken' FROM DUAL UNION ALL
SELECT 1003, 'Jimmy' FROM DUAL UNION ALL
SELECT 1004, 'Jack' FROM DUAL;
COMMIT;
execute dbms_stats.gather_table_stats(ownname = 'ETL', tabname ='TEST', estimate_percent =DBMS_STATS.AUTO_SAMPLE_SIZE, method_opt = 'FOR ALL COLUMNS SIZE AUTO');启用对索引IDX_TEST_ID的监控
ALTER INDEX IDX_TEST_ID MONITORING USAGE;此时观察V$OBJECT_USAGE表数据的变化,如下所示,MONITORIN字段值变为YES,表示索引IDX_TEST_ID已经被置于监控状态。USED字段为NO表示暂时没有SQL使用该索引SQL COL INDEX_NAME FOR A20
SQL COL TABLE_NAME FOR A10
SQL COL MONITORING FOR A10
SQL COL USED FOR A10
SQL COL START_MONITORING FOR A20
SQL COL END_MONITORING FOR A20
SQL SELECT * FROM V$OBJECT_USAGE;
INDEX_NAME TABLE_NAME MONITORING USED START_MONITORING END_MONITORING------------ ---------- ---------- ---- -------------------- ----------------IDX_TEST_ID TEST YES NO 11/28/2015 14:57:41此时我们执行下面SQL,因为此时使用全表扫描,那么索引IDX_TEST_ID依然没有被使用,此时可以查看V$OBJECT_USAGE进行验证。
SQL SET AUTOTRACE ON;
SQL SELECT * FROM TEST WHERE ID =1001;
ID NAME
---------- --------------------------------1001 Kerry
Execution Plan
--------------------------------------------------------------------------------------------------------------------| Id | Operation | Name | Rows | Bytes | Cost |----------------------------------------------------------| 0 | SELECT STATEMENT | | 1 | 9 | 2 || 1 | TABLE ACCESS FULL| TEST | 1 | 9 | 2 |----------------------------------------------------------Note
-----
- 'PLAN_TABLE' is old version
Statistics
----------------------------------------------------------1 recursive calls
0 db block gets
4 consistent gets
0 physical reads
0 redo size
578 bytes sent via SQL*Net to client
492 bytes received via SQL*Net from client2 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
1 rows processed
clip_image001
如下所示,此时索引IDX_TEST_ID依然没有被使用。
clip_image002
我们使用索引提示强制下面SQL使用索引IDX_TEST_IDSELECT /*+ INDEX(TEST IDX_TEST_ID) */* FROM TEST WHERE ID =1001;此时你就会发现USED的值变为了YES了。
clip_image003
ALTER INDEX IDX_TEST_ID NOMONITORING USAGE;执行上面命令后,在V$OBJECT_USAGE表中,就会更新表TEST记录的END_MONITORING、MONITORING的值。
clip_image004
如果你又启用监控索引使用情况,那么系统会更新START_MONITORING、END_MONITORING字段的值(END_MONITORING的值更新为NULL)。如果删除表TEST,此时你会发现V$OBJECT_USAGE对象中关于表TEST的记录也不见了。
注意:SELECT * FROM V$OBJECT_USAGE; 只能查看当前用户下被监控的索引信息。即使sys、system用户也不能查看其它用户的信息。
在测试过程中有个小疑问,就是在准备测试环境时,如果不对表收集统计信息的话,那么即使SQL走全表扫描,你依然发现V$OBJECT_USAGE中索引被标记使用了。如下所示DROP TABLE TEST PURGE;
CREATE TABLE TEST
(
ID NUMBER(10),
NAME VARCHAR2(32)
);
CREATE INDEX IDX_TEST_ID ON TEST(ID);
INSERT INTO TEST
SELECT 1001, 'Kerry' FROM DUAL UNION ALL
SELECT 1002, 'Ken' FROM DUAL UNION ALL
SELECT 1003, 'Jimmy' FROM DUAL UNION ALL
SELECT 1004, 'Jack' FROM DUAL;
COMMIT;
ALTER INDEX IDX_TEST_ID MONITORING USAGE;SQL SET AUTOTRACE ON;
SQL SELECT * FROM TEST WHERE ID =1001;
ID NAME
---------- --------------------------------1001 Kerry
Execution Plan
--------------------------------------------------------------------------------------------------------------------| Id | Operation | Name | Rows | Bytes | Cost |----------------------------------------------------------| 0 | SELECT STATEMENT | | 1 | 31 | 2 || 1 | TABLE ACCESS FULL| TEST | 1 | 31 | 2 |----------------------------------------------------------Note
-----
- 'PLAN_TABLE' is old version
Statistics
----------------------------------------------------------7 recursive calls
0 db block gets
10 consistent gets
0 physical reads
0 redo size
578 bytes sent via SQL*Net to client
492 bytes received via SQL*Net from client2 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
1 rows processed
SQL SELECT * FROM V$OBJECT_USAGE;
INDEX_NAME TABLE_NAME MONITORING USED START_MONITORING END_MONITORING------------ ---------- ---------- ------ ----------- -------------------IDX_TEST_ID TEST YES YES 11/28/2015 15:11:46那么为什么呢? 猜测是在解析生成执行计划时,用到了索引的一些信息,导致V$OBJECT_USAGE表中的字段USED被标记为YES。
如果我们想在系统中监控所有的索引,那么我们可以通过下面脚本实现监控数据库所有的索引。注意我们要排除一些系统表的索引、以及LOB indexes。原因有下面两个:
1:LOB indexes不能修改,否则会报ORA-22864错误(ORA-22864: cannot ALTER or DROP LOB indexes)。
2:ORA-00701: object necessary for warmstarting database cannot be alteredORA-00701: object necessary for warmstarting database cannot be altered00701. 00000 - "object necessary for warmstarting database cannot be altered"*Cause: Attempt to alter or drop a database object (table, cluster, orindex) which are needed for warmstarting the database.
*Action: None.
SET PAGES 999;
SET HEADING OFF;
SPOOL run_monitor.sql
SELECT
'ALTER INDEX '||OWNER||'.'||INDEX_NAME||' MONITORING USAGE;'
FROM
DBA_INDEXES
WHERE
INDEX_TYPE != 'LOB' AND OWNER NOT IN ('SYS', 'SYSMAN', 'SYSTEM', 'MDSYS', 'WMSYS', 'TSMSYS', 'DBSNMP', 'OUTLN');
SPOOL OFF;
@run_monitor.sql
此时使用下面脚本就能查出那些索引是未使用索引,当然监控索引时长非常重要,太短的话有可能导致查询出来的数据有问题,一般建议监控一周后即可,OLAP系统则需要适当延长监控的时间。
SELECT I.TABLE_OWNER,
T.TABLE_NAME,
I.INDEX_NAME,
U.USED,
U.START_MONITORING,
U.END_MONITORING
FROM USER_TABLES T
INNER JOIN USER_INDEXES I
ON T.TABLE_NAME = I.TABLE_NAME
INNER JOIN V$OBJECT_USAGE U
ON U.TABLE_NAME = I.TABLE_NAME
AND I.INDEX_NAME = U.INDEX_NAME
WHERE I.TABLE_OWNER=SYS_CONTEXT('USERENV','CURRENT_USER')另外,博客Oracle - Find unused Indexes中介绍了一个查找没有使用索引的SQL语句。如下所示statspack_unused_indexes.sqlcol owner heading "Index Owner" format a30col index_name heading "Index Name" format a30set linesize 95 trimspool on pagesize 80
select *
from
(select
owner,
index_name
from
dba_indexes di
where
di.index_type != 'LOB'
and
owner not in ('SYS', 'SYSMAN', 'SYSTEM', 'MDSYS', 'WMSYS', 'TSMSYS', 'DBSNMP', 'OUTLN')minus
select
index_owner owner,
index_name
from
dba_constraints dc
where
index_owner not in ('SYS', 'SYSMAN', 'SYSTEM', 'MDSYS', 'WMSYS', 'TSMSYS', 'DBSNMP', 'OUTLN')minus
select
p.object_owner owner,
p.object_name index_name
from
stats$snapshot sn,
stats$sql_plan p,
stats$sql_summary st,
stats$sql_plan_usage spu
where
st.sql_id = spu.sql_id
and
spu.plan_hash_value = p.plan_hash_value
and
st.hash_value = p.plan_hash_value
and
sn.snap_id = st.snap_id
and
sn.dbid = st.dbid
and
sn.instance_number = st.instance_number
and
sn.snap_id = spu.snap_id
and
sn.dbid = spu.snap_id
and
sn.instance_number = spu.instance_number
and
sn.snap_id between begin_snap and end_snapand
p.object_type = 'INDEX'
)
where owner not in ('SYS', 'SYSMAN', 'SYSTEM', 'MDSYS', 'WMSYS', 'TSMSYS', 'DBSNMP', 'OUTLN')order by 1, 2
/
这里是另一个脚本用来跟踪未使用的索引并展示给所有索引的调用计数。最重要的是,这个脚本显示了多列索引引用的列(这个脚本执行时间较长,资源开销较大。)col c1 heading 'Begin|Interval|time' format a20col c2 heading 'Search Columns' format 999col c3 heading 'Invocation|Count' format 99,999,999break on c1 skip 2
accept idxname char prompt 'Enter Index Name: '
ttitle 'Invocation Counts for index|idxname'
select
to_char(sn.begin_interval_time,'yy-mm-dd hh24') c1,p.search_columns c2,count(*) c3from
dba_hist_snapshot sn,
dba_hist_sql_plan p,
dba_hist_sqlstat st
where
st.sql_id = p.sql_id
and
sn.snap_id = st.snap_id
and
p.object_name = 'idxname'
group by
begin_interval_time,search_columns;
通过 监控数据库索引的使用,释放那些未被使用的索引,从而节省维护索引的开销,优化性能。 1、在oracle8i中,确定使用了那个索引的方法意味着要对存在语共享SQL区中的所有语句运行EXPLIAN PALN,然后查询计划表中的OPERATION列,从而识别有OBJECT_OWNER和OBJECT_NAME列所确定的那个索引上的索引访问。 下面是一个监控索引使用的脚本,这个脚本仅仅是一个样品,在某种条件下成立: 条件: 运行这个脚本的用户拥有权限解释所有的v$sqlarea中的sql,除了不是被SYS装载的。plan_table.remarks能够别用来决定与特权习惯的错误。对所有的共享池中SQL,参数OPTIMIZER_GOAL是一个常量,无视v$sqlarea.optimizer_mode。两次快照之间,统计资料被再次分析过。没有语句别截断。所有的对象都是局部的。所有被引用的表或视图或者是被运行脚本的用户所拥有,或者完全有资格的名字或同义词被使用。自从上次快照以来,没有不受"欢迎"的语句被冲洗出共享池(例如,在装载)。 脚本: Code: [Copy to clipboard] set echo off Rem Drop and recreate PLAN_TABLE for EXPLAIN PLAN drop table plan_table; create table PLAN_TABLE ( statement_id varchar2(30), timestamp date, remarks varchar2(80), operation varchar2(30), options varchar2(255), object_node varchar2(128), object_owner varchar2(30), object_name varchar2(30), object_instance numeric, object_type varchar2(30), optimizer varchar2(255), search_columns number, id numeric, parent_id numeric, position numeric, cost numeric, cardinality numeric, bytes numeric, other_tag varchar2(255), partition_start varchar2(255), partition_stop varchar2(255), partition_id numeric, other long, distribution varchar2(30), cpu_cost numeric, io_cost numeric, temp_space numeric, access_predicates varchar2(4000), filter_predicates varchar2(4000)); Rem Drop and recreate SQLTEMP for taking a snapshot of the SQLAREA drop table sqltemp; create table sqltemp ( ADDR VARCHAR2 (16), SQL_TEXT VARCHAR2 (2000), DISK_READS NUMBER, EXECUTIONS NUMBER, PARSE_CALLS NUMBER); set echo on Rem Create procedure to populate the plan_table by executing Rem explain plan...for 'sqltext' dynamically create or replace procedure do_explain ( addr IN varchar2, sqltext IN varchar2) as dummy varchar2 (1100); mycursor integer; ret integer; my_sqlerrm varchar2 (85); begin dummy:='EXPLAIN PLAN SET STATEMENT_ID=' ; dummy:=dummy||''''||addr||'''' ||' FOR '||sqltext; mycursor := dbms_sql.open_cursor; dbms_sql.parse(mycursor,dummy,dbms_sql.v7); ret := dbms_sql.execute(mycursor); dbms_sql.close_cursor(mycursor); commit; exception -- Insert errors into PLAN_TABLE... when others then my_sqlerrm := substr(sqlerrm,1,80); insert into plan_table(statement_id, remarks) values (addr,my_sqlerrm); -- close cursor if exception raised on EXPLAIN PLAN dbms_sql.close_cursor(mycursor); end; / Rem Start EXPLAINing all S/I/U/D statements in the shared pool declare -- exclude statements with v$sqlarea.parsing_schema_id = 0 (SYS) cursor c1 is select address, sql_text, DISK_READS, EXECUTIONS, PARSE_CALLS from v$sqlarea where command_type in (2,3,6,7) and parsing_schema_id != 0; cursor c2 is select addr, sql_text from sqltemp; addr2 varchar(16); sqltext v$sqlarea.sql_text%type; dreads v$sqlarea.disk_reads%type; execs v$sqlarea.executions%type; pcalls v$sqlarea.parse_calls%type; begin open c1; fetch c1 into addr2,sqltext, dreads,execs,pcalls; while (c1%found) loop insert into sqltemp values (addr2,sqltext,dreads,execs,pcalls); commit; fetch c1 into addr2, sqltext,dreads,execs,pcalls; end loop; close c1; open c2; fetch c2 into addr2, sqltext; while (c2%found) loop do_explain(addr2,sqltext); fetch c2 into addr2, sqltext; end loop; close c2; end; / Rem Generate a report of index usage based on the number of times Rem a SQL statement using that index was executed select p.owner, p.name, sum(s.executions) totexec from sqltemp s, (select distinct statement_id stid, object_owner owner, object_name name from plan_table where operation = 'INDEX') p where s.addr = p.stid group by p.owner, p.name order by 2 desc; Rem Perform cleanup on exit (optional) delete from plan_table where statement_id in ( select addr from sqltemp ); drop table sqltemp;关于这个脚本,有几个重要的地方需要注意,即它可能一起明显的开销,因此,应该在仔细地进行 权衡后才把它应用到繁忙的生产应用系统中区。
我们在微信上24小时期待你的声音
解答本文疑问/技术咨询/运营咨询/技术建议/互联网交流