本系列有两部分,我们将在第一部分中讨论,如何为一个新的索引的初始大小做一个适当的评估。已存在的索引如何? 它们的大小是否合适?
现在,如果觉得数据有些陈旧,我们可以将索引的分析结果保存成文本并且运行该文本。这样做不会丢失任何用户: 6Go>||Mn
'NT_%+y
spool c:\analyze_index.sql s%F.. H~
select 'analyze index '||owner||'.'||index_name||' compute statistics;' z' V g
from t_names; ?K,k8s`
spool off ~ e/%Vq\E
@c:\analyze_index adiAU]
运行结果如下: 5_"X[']R
analyze index ORADBA.TASK_DT_REQ compute statistics; >8+8,Q\(`
analyze index ORADBA.TASK_TYPE_FK compute statistics; Zn&#Aq v
analyze index ORADBA.TASK_ENC_FK compute statistics; 5J|J9B'z
analyze index ORADBA.TASK_CLIENT_FK compute statistics; qaRnNr%
analyze index ORADBA.TASK_APPT_FK compute statistics; rUOK{Wy
analyze index ORADBA.TASK_CENTER_FK compute statistics; ]aJ[t
<n)sP0}&X
下一个步骤要求我们授予所移动的索引的用户在新的目标表空间中的权限,你可以通过查看 dba_ts_quotas 和 dba_sys_privs,得知他们是否已经得到权限: _0Q<M
2Ljnp^J
select distinct 'alter user '||owner||' quota unlimited on hrd;' Cv ]F<vMj
from t_names a Es" 2
where not exists (select 'x' from dba_sys_privs ]D3D--I
where a.owner = grantee and rownum =1) T/Bes.xr
and not exists (select 'x' from dba_ts_quotas H/Bfw^[F
where tablespace_name = 'HRD' |Xx*^hw
and a.owner = username and rownum =1); yP # ^4
接着我们得出结论: :?`:A
alter user ORADBA quota unlimited on hrd; G7%xR.K[
lrZ V'5@
完成后,确认已经将我们所改变的用户的权限恢复为0。现在基础工作已经完成,我们可以开始执行真正的移动: k^^7&Bdv;k
d3V"-NAlwY
spool c:\resize_new_index.sql bg-3N8pI
$4FF82
select 'alter index '||a.owner||'.'||a.index_name|| \p"MZxv!`
' rebuild tablespace hrd'||chr(10)|| Xa\%s-79n
' storage(initial '|| P4OsDWfG
((decode(blevel U ~Ln>f
,0,0 ~N35nB7]/
,ceil(a.leaf_blocks/trunc(a.num_rows/a.leaf_blocks))) \}@1%!01
+a.leaf_blocks) fv Fyk
*:block_size)|| .or,H~4a
' next '||a.next_extent|| k[lqv:
' maxextents '||a.max_extents||' pctincrease 0)'|| 9B!j j)q~.
' nologging;' ^n&A>*eX9,
from dba_indexes a W0m594
,dba_segments b [}D$Q*Fa>
,t_names c wdRV3afa
where a.leaf_blocks > 0 utW N`qW9
and a.num_rows > 0 2F?cHHy<
and a.owner not in ('SYS','SYSTEM') \BQ&\jb
and a.index_type != 'BITMAP' -M)YLzR*
and a.last_analyzed is not null 9=1e#,\Q;
and a.owner = b.owner j6v=/Xr
and a.index_name = b.segment_name [=]Li>y(
and a.owner = c.owner l:Q-6|ckTP
and a.index_name = c.index_name +h w:jV
order by (decode(blevel,0,0 7iP 3XTo
,ceil(a.leaf_blocks/trunc(a.num_rows/a.leaf_blocks)))+a.leaf_blocks) 7c}JRxk
; 6Y,sG4,A
spool off y*2 q
运行结果如下: yW +u9=e6
alter index ORADBA.TASK_APPT_FK rebuild tablespace hrd ;Va\vr0;%1
storage(initial 1081344 next 2097152 maxextents 1017 pctincrease 0) >KCS`A *
nologging; r-K^Aa=",
A=f$o 'b
alter index ORADBA.TASK_TYPE_FK rebuild tablespace hrd LcmngM=
storage(initial 1228800 next 2097152 maxextents 1017 pctincrease 0) 0h4%`_
nologging; 3;\kFR9
ka]%NRE
alter index ORADBA.TASK_DT_REQ rebuild tablespace hrd te)l7uRi
storage(initial 1392640 next 65536 maxextents 1017 pctincrease 0) ]AD]O?<`V
nologging; 0 $_3`U;'j
pKPd =
alter index ORADBA.TASK_CENTER_FK rebuild tablespace hrd 4IK=[G
storage(initial 1638400 next 1048576 maxextents 1017 pctincrease 0) (7wLU%5
nologging; K^C~J.aC
V'{^Byaw
alter index ORADBA.TASK_CLIENT_FK rebuild tablespace hrd 8D^S
storage(initial 1671168 next 2097152 maxextents 1017 pctincrease 0) w; im{ T
nologging; ?}Y-G>v!
qh}:^z^
alter index ORADBA.TASK_ENC_FK rebuild tablespace hrd q'"JXh=e/d
storage(initial 1933312 next 2097152 maxextents 1017 pctincrease 0) Zx3k'rG
nologging; getvtO@9
>i>$.sx
结论: wsu=J~
{'R= jFa0$
通过移动、合并、分析然后移回,我们按照正确的大小重新建立了索引,与此同时,我们整理了表空间。索引无时不在,删除索引的风险也随之时刻存在。提醒一句:在你移动索引的时候,用户将受到影响,因此,请选择非繁忙时段进行上述操作。我们不能为了试验数据而丢失客户。 @WqS/ 3?=Y
1$*9^|"l
初始化的extent计算方法如下: H $[" )w
0{+gG^
(number of leaf blocks + number of computed branch blocks) * block size。 r?Y<A4A)
=z fHR
注意:我以索引的大小来排序,这是基于假设较大的索引通常有更多的活动空间,这么做也是为了将来减少碎片所占据的空间。 RX?'ekj+V
Jr3=i
你会注意到这个操作忽略那些行为0或者块为0的空索引。为了初始化extent,这些空索引也应该被重新建立成1个块,或者删除,除非你知道在不久的将来,它们会被数据占用。对于分区索引,可以用同样的查询实现。但是sql语句中要把dba_indexes替换为dba_ind_partitions,分区名必须包含在rebuild 语句中。