Chinaunix首页 | 论坛 | 博客
  • 博客访问: 632563
  • 博文数量: 825
  • 博客积分: 5000
  • 博客等级: 大校
  • 技术积分: 4980
  • 用 户 组: 普通用户
  • 注册时间: 2008-10-27 14:19
文章分类

全部博文(825)

文章存档

2011年(1)

2008年(824)

我的朋友

分类:

2008-10-27 14:28:07


  [Q]如果设置自动跟踪
  [A]用system登录
  执行$ORACLE_HOME/rdbms/admin/utlplan.sql创建计划表
  执行$ORACLE_HOME/rdbms/admin/plustrce.sql创建plustrace角色
  如果想计划表让每个用户都能使用,则
  SQL>create public synonym plan_table for plan_table;
  SQL> grant all on plan_table to public;
  如果想让自动跟踪的角色让每个用户都能使用,则
  SQL> grant plustrace to public;
  通过如下语句开启/停止跟踪
  SET AUTOTRACE ON |OFF
  | ON EXPLAIN | ON STATISTICS | TRACEONLY | TRACEONLY EXPLAIN
  
  [Q]如果跟踪自己的会话或者是别人的会话
  [A]跟踪自己的会话很简单
  Alter session set sql_trace true|false
  Or
  Exec dbms_session.set_sql_trace(TRUE);
  如果跟踪别人的会话,需要调用一个包
  exec dbms_system.set_sql_trace_in_session(sid,serial#,true|false)
  跟踪的信息在user_dump_dest 目录下可以找到或通过如下脚本获得文件名称(适用于Win环境,如果是unix需要做一定修改)
  SELECT p1.value||'\'||p2.value||'_ora_'||p.spid||'.ora' filename
  FROM
  v$process p,
  v$session s,
  v$parameter p1,
  v$parameter p2
  WHERE p1.name = 'user_dump_dest'
  AND p2.name = 'db_name'
  AND p.addr = s.paddr
  AND s.audsid = USERENV ('SESSIONID')
  最后,可以通过Tkprof来解析跟踪文件,如
  Tkprof 原文件 目标文件 sys=n
  
  
  [Q]怎么设置整个数据库系统跟踪
  [A]其实文档上的alter system set sql_trace=true是不成功的
  但是可以通过设置事件来完成这个工作,作用相等
  alter system set events
  '10046 trace name context forever,level 1';
  如果关闭跟踪,可以用如下语句
  alter system set events
  '10046 trace name context off';
  其中的level 1与上面的8都是跟踪级别
  level 1:跟踪SQL语句,等于sql_trace=true
  level 4:包括变量的详细信息
  level 8:包括等待事件
  level 12:包括绑定变量与等待事件
  
  [Q]怎么样根据OS进程快速获得DB进程信息与正在执行的语句
  [A]有些时候,我们在OS上操作,象TOP之后我们得到的OS进程,怎么快速根据OS信息获得DB信息呢?
  我们可以编写如下脚本:
  $more whoit.sh
  #!/bin/sh
  sqlplus /nolog <  connect / as sysdba
  col machine format a30
  col program format a40
  set line 200
  select sid,serial# ,username,osuser,machine,program,process,to_char(logon_time,'yyyy/mm/dd hh24:mi:ss')
  from v\$session where paddr in
  ( select addr from v\$process where spid in($1));
  
  select sql_text from v\$sqltext_with_newlines
  where hash_value in
  (select SQL_HASH_VALUE from v\$session where
  paddr in (select addr from v\$process where spid=$1)
  )
  order by piece;
  
  exit;
  EOF
  然后,我们只要在OS环境下如下执行即可
  $./whoit.sh Spid
  
  [Q]怎么样分析表或索引
  [A]命令行方式可以采用analyze命令
  如Analyze table tablename compute statistics;
  Analyze index|cluster indexname estimate statistics;
  ANALYZE TABLE tablename COMPUTE STATISTICS
  FOR TABLE
  FOR ALL [LOCAL] INDEXES
  FOR ALL [INDEXED] COLUMNS;
  ANALYZE TABLE tablename DELETE STATISTICS
  ANALYZE TABLE tablename VALIDATE REF UPDATE
  ANALYZE TABLE tablename VALIDATE STRUCTURE
  [CASCADE]|[INTO TableName]
  ANALYZE TABLE tablename LIST CHAINED ROWS [INTO TableName]
  等等。
  如果想分析整个用户或数据库,还可以采用工具包,可以并行分析
  Dbms_utility(8i以前的工具包)
  Dbms_stats(8i以后提供的工具包)
  如
  dbms_stats.gather_schema_stats(User,estimate_percent=>100,cascade=> TRUE);
  dbms_stats.gather_table_stats(User,TableName,degree => 4,cascade => true);
  这是对命令与工具包的一些总结
  1、对于分区表,建议使用DBMS_STATS,而不是使用Analyze语句。
  a) 可以并行进行,对多个用户,多个Table
  b) 可以得到整个分区表的数据和单个分区的数据。
  c) 可以在不同级别上Compute Statistics:单个分区,子分区,全表,所有分区
  d) 可以倒出统计信息
  e) 可以用户自动收集统计信息
  2、DBMS_STATS的缺点
  a) 不能Validate Structure
  b) 不能收集CHAINED ROWS, 不能收集CLUSTER TABLE的信息,这两个仍旧需要使用Analyze语句。
  c) DBMS_STATS 默认不对索引进行Analyze,因为默认Cascade是False,需要手工指定为True
  3、对于oracle 9里面的External Table,Analyze不能使用,只能使用DBMS_STATS来收集信息。
  
  [Q]怎么样快速重整索引
  [A]通过rebuild语句,可以快速重整或移动索引到别的表空间
  rebuild有重建整个索引数的功能,可以在不删除原始索引的情况下改变索引的参数
  语法为
  alter index index_name rebuild tablespace ts_name
  storage(……);
  如果要快速重建整个用户下的索引,可以用如下脚本,当然,需要根据你自己的情况做相应修改
  SQL> set heading off
  SQL> set feedback off
  SQL> spool d:\index.sql
  SQL> SELECT 'alter index ' || index_name || ' rebuild '
  ||'tablespace INDEXES storage(initial 256K next 256K pctincrease 0);'
  FROM all_indexes
  WHERE ( tablespace_name != 'INDEXES'
  OR next_extent != ( 256 * 1024 )
  )
  AND owner = USER
  SQL>spool off
  另外一个合并索引的语句是
  alter index index_name coalesce,这个语句仅仅是合并索引中同一级的leaf block
  消耗不大,对于有些索引中存在大量空间浪费的情况下,有一些作用。
  
  [Q]如何使用Hint提示
  [A] 在select/delete/update后写/*+ hint */
  如 select /*+ index(TABLE_NAME INDEX_NAME) */ col1...
  注意/*和+之间不能有空格
  如用hint指定使用某个索引
  
  select /*+ index(cbotab) */ col1 from cbotab;
  select /*+ index(cbotab cbotab1) */ col1 from cbotab;
  select /*+ index(a cbotab1) */ col1 from cbotab a;
  其中
  TABLE_NAME是必须要写的,且如果在查询中使用了表的别名,在hint也要用表的别名来代替表名;
  INDEX_NAME可以不必写,会根据统计值选一个索引;
  如果索引名或表名写错了,那这个hint就会被忽略;
  
  [Q]怎么样快速复制表或者是插入数据
  [A]快速复制表可以指定Nologging选项
  如:Create table t1 nologging
  as select * from t2;
  快速插入数据可以指定append提示,但是需要注意
  noarchivelog模式下,默认用了append就是nologging模式的。
  在archivelog下,需要把表设置程Nologging模式。
  如insert /*+ append */ into t1
  select * from t2
  注意:如果在9i环境中并设置了FORCE LOGGING,则以上操作是无效的,并不会加快,当然,可以通过如下语句设置为NO FORCE LOGGING。
  Alter database no force logging;
  是否开启了FORCE LOGGING,可以用如下语句查看
  SQL> select force_logging from v$database;
  
  [Q]怎么避免使用特定索引
  [A]在很多时候,会错误的使用索引而导致效率的明显下降,我们可以使用一点点技巧而避免使用不该使用的索引,如:
  表test,有字段a,b,c,d,在a,b,c上建立联合索引inx_a(a,b,c),在b上单独建立了一个索引Inx_b(b)。
  在正常情况下,where a=? and b=? and c=?会用到索引inx_a,
  where b=?会用到索引inx_b
  但是,where a=? and b=? and c=? group by b会用到哪个索引呢?在分析数据不正确(很长时间没有分析)或根本没有分析数据的情况下,oracle往往会使用索引inx_b。通过执行计划的分析,这个索引的使用,将大大耗费查询时间。
  当然,我们可以通过如下的技巧避免使用inx_b,而使用inx_a。
  where a=? and b=? and c=? group by b||'' --如果b是字符
  where a=? and b=? and c=? group by b+0 --如果b是数字
  通过这样简单的改变,往往可以是查询时间提交很多倍
  当然,我们也可以使用no_index提示,相信很多人没有用过,也是一个不错的方法:
  select /*+ no_index(t,inx_b) */ * from test t
  where a=? and b=? and c=? group by b
  
  [Q]Oracle什么时候会使用跳跃式索引扫描
  [A]这是9i的一个新特性跳跃式索引扫描(Index Skip Scan).
  例如表有索引index(a,b,c),当查询条件为
  where b=?的时候,可能会使用到索引index(a,b,c)
  如,执行计划中出现如下计划:
  INDEX (SKIP SCAN) OF 'TEST_IDX' (NON-UNIQUE)
  Oracle的优化器(这里指的是CBO)能对查询应用Index Skip Scans至少要有几个
【责编:admin】

--------------------next---------------------

阅读(288) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~