Oracle 聚簇因子

前几天被人问到聚簇因子被问住了,所以今天做了个试验说明这个问题
1、准备试验条件

--创建表t_1
CREATE TABLE t_1
AS
SELECT ROWNUM rn,a.* FROM all_objects a ORDER BY object_name DESC;

--创建t_1表关于rownum索引
CREATE INDEX ind_t_1 ON t_1(rn);

--创建表表t_2
CREATE TABLE t_2
AS
SELECT * FROM (
SELECT ROWNUM rn,a.* FROM all_objects a ) ORDER BY rn ASC;

--创建t_2表关于rownum索引
CREATE INDEX ind_t_2 ON t_2(rn);

--分析两张表及其索引
EXEC DBMS_STATS.gather_table_stats(USER, 'T_1');
EXEC DBMS_STATS.gather_table_stats(USER, 'T_2');
EXEC DBMS_STATS.gather_index_stats(USER, 'IND_T_1');
EXEC DBMS_STATS.gather_index_stats(USER, 'IND_T_2');

--说明:两个表的区别就是t_2表中的rn是有序的,刚刚建立t_2表的索引一致

2、执行查询操作
SQL> set autot traceonly stat;
SQL> SELECT * FROM t_1 WHERE rn BETWEEN 100 AND 120;

已选择21行。

统计信息
———————————————————-
0 recursive calls
0 db block gets
17 consistent gets
0 physical reads
0 redo size
1807 bytes sent via SQL*Net to client
357 bytes received via SQL*Net from client
3 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
21 rows processed

SQL> SELECT * FROM t_2 WHERE rn BETWEEN 100 AND 120;

已选择21行。

统计信息
———————————————————-
0 recursive calls
0 db block gets
7 consistent gets
0 physical reads
0 redo size
1807 bytes sent via SQL*Net to client
357 bytes received via SQL*Net from client
3 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
21 rows processed

3、观察试验结果
通过执行统计信息观察,t_1表的查询一致读是17,而t_2表的一致读只有7,尽然t_1的一致读尽然是t_2的2倍还多,是不是有点奇怪,同样的表结构,同样的数据(t_2多两条数据)

4、分析原因
通过查询聚簇因子发现,两个表的聚簇因子差别很大,基于rn的索引在rn是顺序排列的表中,clustering_factor的值相差很大。
在表中数据有时候属于无序状态,这个时候的CLUSTERING_FACTOR比较接近NUM_ROWS,说明如 果扫描整个表,每次都要根据Index来读取相应行的RowID,这个时候的IO操作很多,自然检索时间会比较长。如果数据有序的 话,CLUSTERING_FACTOR比较接近BLOCKS,说明相邻的数据在一个块中,减少了IO操作数量,自然检索时间会大大降低。

MYSQL修改密码

方法一
(适用于管理员或者有全局权限的用户重设其它用户的密码)
进入命令行模式
mysql -u root mysql
mysql> UPDATE user SET password=PASSWORD(“new password”) WHERE user=’name’;
mysql> FLUSH PRIVILEGES;
mysql> QUIT

方法二
(应用同上,只是方法不同)
mysql -u root mysql
mysql> SET PASSWORD FOR name=PASSWORD(‘new password’);
mysql> QUIT

方法三
mysqladmin -u root “old password” “new password”

ORA-38760: 此数据库实例无法启用闪回数据库

SQL> startup
ORACLE 例程已经启动。

Total System Global Area 368263168 bytes
Fixed Size 1374668 bytes
Variable Size 276825652 bytes
Database Buffers 83886080 bytes
Redo Buffers 6176768 bytes
数据库装载完毕。
ORA-38760: 此数据库实例无法启用闪回数据库

SQL> alter database flashback off;

数据库已更改。

SQL> alter database open;

数据库已更改。

SQL> alter database flashback on;

数据库已更改。

说明:如果出现以下错误,处理如下
SQL> alter database open;
alter database open
*
ERROR at line 1:
ORA-38760: This database instance failed to turn on flashback database

SQL> select name from v$restore_point;

If so, drop them:
SQL> drop restore point ;
SQL> alter database flashback off;

.

ORA-01207/ORA-00338恢复

1、模拟环境
拷贝出来控制文件,然后对数据库进行一些操作,然后关闭数据库,使用拷贝出来的控制文件替换原控制文件,启动数据库
出现类此错误:
ORA-00338: 日志 2 (用于线程 1) 比控制文件更新
ORA-00312: 联机日志 2 线程 1: ‘E:\ORACLE\ORADATA\XFF\REDO02’
或者
ORA-01122: 数据库文件 1 验证失败
ORA-01110: 数据文件 1: ‘E:\ORACLE\ORADATA\XFF\SYSTEM01.DBF’
ORA-01207: 文件比控制文件更新 – 旧的控制文件

2、处理思路
1)创建控制文件
1.1)alter database backup controlfile to trace;
1.2)生成控制文件脚本

STARTUP NOMOUNT
CREATE CONTROLFILE REUSE DATABASE "XFF" NORESETLOGS  ARCHIVELOG
    MAXLOGFILES 16
    MAXLOGMEMBERS 3
    MAXDATAFILES 100
    MAXINSTANCES 8
    MAXLOGHISTORY 584
LOGFILE
  GROUP 1 'E:\ORACLE\ORADATA\XFF\REDO01'  SIZE 10M BLOCKSIZE 512,
  GROUP 2 'E:\ORACLE\ORADATA\XFF\REDO02'  SIZE 10M BLOCKSIZE 512,
  GROUP 3 'E:\ORACLE\ORADATA\XFF\REDO03'  SIZE 10M BLOCKSIZE 512
DATAFILE
  'E:\ORACLE\ORADATA\XFF\SYSTEM01.DBF',
  'E:\ORACLE\ORADATA\XFF\SYSAUX01.DBF',
  'E:\ORACLE\ORADATA\XFF\UNDOTBS01.DBF',
  'E:\ORACLE\ORADATA\XFF\USERS01.DBF',
  'E:\ORACLE\ORADATA\XFF\EXAMPLE01.DBF',
  'E:\ORACLE\ORADATA\XFF\O_ORACLE.DBF',
  'E:\ORACLE\ORADATA\XFF\XIFENFEI01.DBF',
  'E:\ORACLE\ORADATA\XFF\P_TEST01.DBF',
  'E:\ORACLE\ORADATA\XFF\SYS_MG01.DBF',
  'E:\ORACLE\ORADATA\XFF\P101.DBF',
  'E:\ORACLE\ORADATA\XFF\P201.DBF',
  'E:\ORACLE\ORADATA\XFF\P301.DBF',
  'E:\ORACLE\ORADATA\XFF\OGG01.DBF',
  'E:\ORACLE\ORADATA\XFF\SPOT01.DBF'
CHARACTER SET ZHS16GBK
;

1.3)关闭数据库
shutdown abort;

1.4)删除现在的控制文件
1.5)执行生成控制文件脚本

2)恢复数据库
recover database;

3)打开数据库
alter database open;

4)添加临时文件
alter tablespace temp add tempfile
‘E:\ORACLE\ORADATA\XFF\TEMP01.DBF’ size 20m reuse;

说明:可以使用备份的控制文件进行恢复
1:startup mount;
2:recover database using backup controlfile until cancel;
然后根据情况,指定archive log和redo file。
3:alter database open resetlogs;

latch: cache buffers chains

当一个数据块读入sga区,相应的buffer header会被放置到hash列表上,我们称其这hash chains,chain在中文的意为链条或串的意思,表达就是关连性.如果一个进程想访问或修改hash chain上的block,它首先要获得”cache buffers chains” latch。

原因一:低效率的SQL语句(主要体现在逻辑读过高)
cache buffers chains latch很大程度与逻辑读有关,所以要观注v$sql中BUFFER_GETS/EXECUTIONS大的语句。
同时每一个逻辑读需要一个latch get 操作及一个cpu操作,这样的sql也会很耗cpu资源。

原因二:热块(访问过于频繁)
找出热点块方法一:

--找出p1raw
select p1,p1raw from v$session_wait where event='latch: cache buffers chains';

--找到对象
SELECT /*+ RULE */
 E.OWNER || '.' || E.SEGMENT_NAME SEGMENT_NAME,
 E.PARTITION_NAME,
 E.EXTENT_ID EXTENT#,
 X.DBABLK - E.BLOCK_ID + 1 BLOCK#,
 X.TCH,
 L.CHILD#
  FROM SYS.V$LATCH_CHILDREN L, SYS.X$BH X, SYS.DBA_EXTENTS E
 WHERE X.HLADDR = '00000002576EE018'--p1raw
   AND E.FILE_ID = X.FILE#
   AND X.HLADDR = L.ADDR
   AND X.DBABLK BETWEEN E.BLOCK_ID AND E.BLOCK_ID + E.BLOCKS - 1
 ORDER BY X.TCH DESC;

找出热点块方法二:

--直接找出热点块
SELECT OBJECT_NAME, SUBOBJECT_NAME
  FROM DBA_OBJECTS
 WHERE DATA_OBJECT_ID IN
       (SELECT DATA_OBJECT_ID
          FROM (SELECT OBJ DATA_OBJECT_ID, FILE#, DBABLK, CLASS, STATE, TCH
                  FROM X$BH
                 WHERE HLADDR IN (SELECT ADDR
                                    FROM (SELECT ADDR
                                            FROM V$LATCH_CHILDREN
                                           ORDER BY (GETS + MISSES + SLEEPS) DESC)
                                   WHERE ROWNUM < 10)
                 ORDER BY TCH DESC)
         WHERE ROWNUM < 10);