重建索引一定能提高索引儲存空間利用率和效率嗎?
在日常交流中經常聽到一個錯誤的觀點,資料庫索引需要重建,理由是重建索引至少能有以下好處:
1、索引的重建,即使不能提高效能,也可以壓縮索引的儲存空間,使得單位索
引資料塊所包含的索引更多,效率更高;
2、節省資料庫的儲存空間
但實際上,我們不要盲目的重建索引,有可能重建索引造成索引的儲存空間佔用更大,效率更低。所以重建以前,最好對索引進行分析,檢視索引的當前情況,以確定是否要重建。
以下是Richard Foote的三個具有代表性的實驗:
實驗一:建立一個普通表,表的數值是連續
SQL>create table test1(id number);
SQL>create index test1_idx on test1(id);
SQL>insert into test1 select rownum from dual connect by level<=1000000;
SQL>commit;
SQL>analyze index test1_idx validate structure;
SQL>select blocks, lf_blks, btree_space, pct_used from index_stats;
BLOCKS LF_BLKS BTREE_SPACE PCT_USED
------------------ ------------------- -------------------------- ---------------------
2048 1999 16016116 100
以上PCT_USED已經達到的最佳狀態100%,如果對索引重建,會增大索引的儲存空間:
SQL>alter index test1_idx rebuild;
SQL>analyze index test1_idx validate structure;
SQL>select blocks, lf_blks, btree_space, pct_used from index_stats;
BLOCKS LF_BLKS BTREE_SPACE PCT_USED
------------------ ------------------- -------------------------- ---------------------
2304 2226 17839236 90
實驗二:建立小表,生成隨機數
SQL>create table test2 (id number);
SQL>insert into test2 select ceil(dbms_random.value(0, 100000))
from dual
connect by level<=1000000;
SQL>commit;
SQL>create index test2_idx on test2(id);
SQL>insert into test2 select ceil(dbms_random.value(1,100000))
from dual connect by level<=50000;
SQL>commit;
SQL>analyze index test2_idx validate structure;
SQL>select blocks, lf_blks, btree_space, pct_used from index_stats;
BLOCKS LF_BLKS BTREE_SPACE PCT_USED
-------------------- -------------------- ----------------------- -----------------------
2304 2216 17767304 95
我們對索引重建,也將增加索引空間的使用:
SQL>alter index test2_idx rebuild;
SQL>analyze index test2_idx validate structure;
SQL>select blocks, lf_blks, btree_space, pct_used from index_stats;
BLOCKS LF_BLKS BTREE_SPACE PCT_USED
------------------ ------------------- -------------------------- ---------------------
2304 2226 17839236 90
實驗三:與實驗二相類似,但增加了一個批量的update,我們通常認為update後會造成索引空間的浪費,所以需要重建索引,能有效降低索引的儲存空間,但實際上,並不是這麼回事。
SQL>create table test3 (id number, value number);
SQL>insert into test3 select rownum, ceil(dbms_random.value(0, 100000))
from dual connect by level<=100000;
SQL>commit;
SQL>create index test3_idx on test3(value);
SQL>insert into test3 select rownum+100000,
ceil(dbms_random.value(0,100000)) from dual
connect by level <=5000;
SQL>commit;
執行以下儲存過程,更新約為10%的資料
begin
for i in 1..10500 loop
update test3 set value =ceil(dbms_random.value(0,100000))
where id=i;
commit;
end loop;
end;
SQL>analyze index test3_idx validate structure;
SQL>select blocks, lf_blks, btree_space, pct_used from index_stats;
BLOCKS LF_BLKS BTREE_SPACE PCT_USED
------------------ ------------------- -------------------------- ---------------------
256 223 1791136 94
SQL>select del_lf_rows from index_stats;
DEL_LF_ROWS
-----------
110
我們更新了約10%的行(10500),但實際上索引儲存空間標識為刪除的110行,證明了大部分索引空間被重用。
重新建立索引,增加索引的儲存空間:
SQL>alter index test3_idx rebuild;
SQL>analyze index test3_idx validate structure;
SQL>select blocks, lf_blks, btree_space, pct_used from index_stats;
BLOCKS LF_BLKS BTREE_SPACE PCT_USED
-------------------- ------------------- -------------------------- ---------------------
256 233 1871096 90
1、索引的重建,即使不能提高效能,也可以壓縮索引的儲存空間,使得單位索
引資料塊所包含的索引更多,效率更高;
2、節省資料庫的儲存空間
但實際上,我們不要盲目的重建索引,有可能重建索引造成索引的儲存空間佔用更大,效率更低。所以重建以前,最好對索引進行分析,檢視索引的當前情況,以確定是否要重建。
以下是Richard Foote的三個具有代表性的實驗:
實驗一:建立一個普通表,表的數值是連續
SQL>create table test1(id number);
SQL>create index test1_idx on test1(id);
SQL>insert into test1 select rownum from dual connect by level<=1000000;
SQL>commit;
SQL>analyze index test1_idx validate structure;
SQL>select blocks, lf_blks, btree_space, pct_used from index_stats;
BLOCKS LF_BLKS BTREE_SPACE PCT_USED
------------------ ------------------- -------------------------- ---------------------
2048 1999 16016116 100
以上PCT_USED已經達到的最佳狀態100%,如果對索引重建,會增大索引的儲存空間:
SQL>alter index test1_idx rebuild;
SQL>analyze index test1_idx validate structure;
SQL>select blocks, lf_blks, btree_space, pct_used from index_stats;
BLOCKS LF_BLKS BTREE_SPACE PCT_USED
------------------ ------------------- -------------------------- ---------------------
2304 2226 17839236 90
實驗二:建立小表,生成隨機數
SQL>create table test2 (id number);
SQL>insert into test2 select ceil(dbms_random.value(0, 100000))
from dual
connect by level<=1000000;
SQL>commit;
SQL>create index test2_idx on test2(id);
SQL>insert into test2 select ceil(dbms_random.value(1,100000))
from dual connect by level<=50000;
SQL>commit;
SQL>analyze index test2_idx validate structure;
SQL>select blocks, lf_blks, btree_space, pct_used from index_stats;
BLOCKS LF_BLKS BTREE_SPACE PCT_USED
-------------------- -------------------- ----------------------- -----------------------
2304 2216 17767304 95
我們對索引重建,也將增加索引空間的使用:
SQL>alter index test2_idx rebuild;
SQL>analyze index test2_idx validate structure;
SQL>select blocks, lf_blks, btree_space, pct_used from index_stats;
BLOCKS LF_BLKS BTREE_SPACE PCT_USED
------------------ ------------------- -------------------------- ---------------------
2304 2226 17839236 90
實驗三:與實驗二相類似,但增加了一個批量的update,我們通常認為update後會造成索引空間的浪費,所以需要重建索引,能有效降低索引的儲存空間,但實際上,並不是這麼回事。
SQL>create table test3 (id number, value number);
SQL>insert into test3 select rownum, ceil(dbms_random.value(0, 100000))
from dual connect by level<=100000;
SQL>commit;
SQL>create index test3_idx on test3(value);
SQL>insert into test3 select rownum+100000,
ceil(dbms_random.value(0,100000)) from dual
connect by level <=5000;
SQL>commit;
執行以下儲存過程,更新約為10%的資料
begin
for i in 1..10500 loop
update test3 set value =ceil(dbms_random.value(0,100000))
where id=i;
commit;
end loop;
end;
SQL>analyze index test3_idx validate structure;
SQL>select blocks, lf_blks, btree_space, pct_used from index_stats;
BLOCKS LF_BLKS BTREE_SPACE PCT_USED
------------------ ------------------- -------------------------- ---------------------
256 223 1791136 94
SQL>select del_lf_rows from index_stats;
DEL_LF_ROWS
-----------
110
我們更新了約10%的行(10500),但實際上索引儲存空間標識為刪除的110行,證明了大部分索引空間被重用。
重新建立索引,增加索引的儲存空間:
SQL>alter index test3_idx rebuild;
SQL>analyze index test3_idx validate structure;
SQL>select blocks, lf_blks, btree_space, pct_used from index_stats;
BLOCKS LF_BLKS BTREE_SPACE PCT_USED
-------------------- ------------------- -------------------------- ---------------------
256 233 1871096 90
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/354732/viewspace-605540/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 【索引】Oracle查詢指定索引提高查詢效率索引Oracle
- oracle重建索引(一)Oracle索引
- 唯一索引和非唯一索引ROWID儲存的區別索引
- 什麼是行儲存和列儲存?正排索引和倒排索引?MySQL既不是倒排索引,也索引MySql
- MySQL索引之空間索引(SPATIAL)MySql索引
- 空間索引 - 各資料庫空間索引使用報告索引資料庫
- 深入淺出空間索引:為什麼需要空間索引索引
- oracle 索引分析及索引重建Oracle索引
- SQL Server 深入解析索引儲存(聚集索引)SQLServer索引
- 索引儲存小記索引
- oracle重建索引Oracle索引
- 透過空間佔用和執行計劃瞭解SQL Server的行儲存索引SQLServer索引
- 使用了索引就一定能避免cache buffers chains爭用嗎索引AI
- 淺談索引系列之索引重建索引
- SQL Server 深入解析索引儲存(非聚集索引)SQLServer索引
- SQLServeronLinux列儲存索引SQLServerLinux索引
- 函式索引的儲存函式索引
- oracle重建索引(三)Oracle索引
- oracle重建索引(二)Oracle索引
- 索引的重建命令索引
- sqlserver 全部索引重建SQLServer索引
- MSSQL Rebuild(重建)索引SQLRebuild索引
- 轉載-treedump索引讀取索引儲存的資料值--非唯一性索引索引
- 工作筆記 - 調整索引和表空間筆記索引
- oracle 估算一個索引所需要的空間Oracle索引
- Oracle表與索引的分析及索引重建Oracle索引
- 深入淺出空間索引:2索引
- 2_mysql(索引、儲存引擎)MySql索引儲存引擎
- sqlserver索引重建和索引重組的區別和操作方法SQLServer索引
- oracle批量重建索引方法Oracle索引
- 談談MYSQL索引是如何提高查詢效率的MySql索引
- 利用索引提高SQL Server資料處理的效率索引SQLServer
- Oracle表與索引的分析及索引重建(轉)Oracle索引
- PostgreSQL儲存智慧-空間聚集儲存SQL
- Oracle 表的移動和索引的重建Oracle索引
- hadoop異構儲存+lucene索引Hadoop索引
- SQL Server 深入解析索引儲存(上)SQLServer索引
- SQL Server 深入解析索引儲存(中)SQLServer索引