㈠ 哪位大哥知道,如何用sql語句清理數據表的碎片!
打開企業管理器,選擇你所要收縮的資料庫,然後在你選擇資料庫的右側窗口中空白處單擊右鍵,選擇所有任務,再選擇收縮資料庫,單擊確定。推薦http://bbs.csdn.net/topics/70440536
㈡ 清理資料庫碎片SQL語句
清除資料庫日誌語句
--清除sqlserver 2000/2005 資料庫日誌
替換下紅字部分資料庫名稱
declare @databasename varchar(15)
select @databasename='hdjjgl_journal'
DUMP TRANSACTION @databasename WITH NO_LOG
BACKUP LOG @databasename WITH NO_LOG
DBCC SHRINKDATABASE(@databasename)
或者
USE 資料庫名
DUMP TRANSACTION 資料庫名 WITH NO_LOG
BACKUP LOG 資料庫名 WITH NO_LOG
DBCC SHRINKFILE(2)
**********************************
--清除sqlserver 2008 資料庫日誌 ,執行兩遍
替換下紅字部分資料庫名稱,建立datalogbak清楚的日誌備份文件夾,注意路徑自定義。
use gdzjg_journal
declare @databasename varchar(100)
declare @databasenamelog varchar(100)
declare @databasenamedir varchar(100)
select @databasename='gdzjg_journal'
select @databasenamelog=@databasename+'_log'
select @databasenamedir='g:\datalogbak\'+@databasename
BACKUP LOG @databasename to disk=@databasenamedir
DBCC SHRINKFILE (@databasenamelog,1)
或者
ALTER DATABASE 資料庫名稱SET RECOVERY SIMPLE
ALTER DATABASE 資料庫名稱SET RECOVERY FULL
DBCC SHRINKDATABASE(資料庫名稱,0)
sqlserver 2000、2008會保存所有的資料庫操作過程,將指令保存在ldf文件中,如果誤刪除數據,想恢復數據的話,可以通過Lumigent Log Explorer For SQLServer 軟體分析ldf文件,可以看到所有執行過的insert、update、delete數據,導出來再逆向執行即可,本人曾經用過一回,確實奏效。
1、sql server 2000清理資料庫日誌
USE 資料庫名
DUMP TRANSACTION 資料庫名 WITH NO_LOG
BACKUP LOG 資料庫名 WITH NO_LOG
DBCC SHRINKFILE(2)
SHRINKFILE(2),後面的2是file_id,可以在當前資料庫用select * from sysfiles看得到,看資料庫的log文件的fileid是多少,正常情況下log的ldf文件是2,mdf文件的fileid是1。
這個查詢語句可以隨時執行,不影響資料庫的運行。
sql server 2005、2008清理資料庫日誌
USE 資料庫名
ALTER DATABASE 資料庫名 SET RECOVERY SIMPLE
ALTER DATABASE 資料庫名 SET RECOVERY FULL
DBCC SHRINKDATABASE(資料庫名,0)
這個查詢語句可以隨時執行,不影響資料庫的運行。
清理ldf的操作可以使用sql server代理,每天自動執行一次,就不怕文件增長撐爆硬碟了。
2、一般mdf用不著收縮,收縮多了容易產生文件碎片,因為delete數據之後,mdf文件中可用頁面空間會保留在那裡,等下次有新數據進來時,會繼續使用。如果實在要清理,可以參考下面的語句:
sql server 2000、2005、2008 收縮mdf文件
DBCC SHRINKDATABASE(資料庫名)
DBCC SHRINKFILE(1,0)
DBCC UPDATEUSAGE(0)
執行上述操作後,你會發現mdf的文件減少了,ldf的文件增大了,再用上面1的日誌清理操作一次即可。
3、最後再附送一個查看數據表的行數、佔用文件空間、存儲情況的查詢語句
-- drop table #test
create table #test(
name varchar(50),
rows int,
reserved varchar(20),
data varchar(20),
index_size varchar(20),
unused varchar(20)
)
set nocount on
insert into #test
EXEC sp_MSforeachtable @command1="sp_spaceused '?'"
select * from #test order by cast(replace(reserved,'KB','') as int) desc
㈢ 為什麼sql server資料庫索引碎片整理
本文需要你對索引和SQL中數據的存儲方式有一定了解
在SQL Server中,存儲數據的最小單位是頁,每一頁所能容納的數據為8060位元組.而頁的組織方式是通過B樹結構(表上沒有聚集索引則為堆結構,不在本文討論之列)如下圖:
在聚集索引B樹中,只有葉子節點實際存儲數據,而其他根節點和中間節點僅僅用於存放查找葉子節點的數據.
每一個葉子節點為一頁,每頁是不可分割的. 而SQL Server向每個頁內存儲數據的最小單位是表的行(Row).當葉子節點中新插入的行或更新的行使得葉子節點無法容納當前更新或者插入的行時,分頁就產生了.在分頁的過程中,就會產生碎片.
理解外部碎片
首先,理解外部碎片的這個「外」是相對頁面來說的。外部碎片指的是由於分頁而產生的碎片.比如,我想在現有的聚集索引中插入一行,這行正好導致現有的頁空間無法滿足容納新的行。從而導致了分頁:
因為在SQL SERVER中,新的頁是隨著數據的增長不斷產生的,而聚集索引要求行之間連續,所以很多情況下分頁後和原來的頁在磁碟上並不連續.
㈣ sql索引碎片如何自動整理用代碼可以實現嗎
重建索引就可以了
重建索引命令:
DBCC DBREINDEX (表名, '')
㈤ sqlserver2008 怎麼定時清理索引碎片
索引碎片判斷及整理、自動維護清理索引碎片
http://blog.csdn.net/zhaowenzhong/article/details/6980894
㈥ sql2005 表中索引碎片總計66+%,優化問題,,,
重建後的索引,應該不包含碎片的。如果還有碎片,很有可能是因為文件系統的碎片導致。
如果你是用windows系統的本地磁碟,是很有可能出現這種問題的。
嘗試做一次磁碟碎片整理。有可能會緩解這個問題。
當然,如果你是掛載的其他存儲設備,以上推論無效。
另外,關於視圖查詢不出來的問題,先確定一下是不是sql性能問題。
比如你的sql裡面是否用了適合的索引,還有就是sql是否過於復雜了?
一般來說如果是比較好的sql,不會因為索引的碎皮問題,導致查不出結果的。
㈦ 判斷MS SQL是否有索引碎片及解決方法
--如何知道是否發生了索引碎片
SELECT object_name(dt.object_id) Tablename,si.name
IndexName,dt.avg_fragmentation_in_percent AS
ExternalFragmentation,dt.avg_page_space_used_in_percent AS
InternalFragmentation
FROM
(
SELECT object_id,index_id,avg_fragmentation_in_percent,avg_page_space_used_in_percent
FROM sys.dm_db_index_physical_stats (db_id('DB_DJSMS'),null,null,null,'DETAILED'
)
WHERE index_id <> 0) AS dt INNER JOIN sys.indexes si ON si.object_id=dt.object_id
AND si.index_id=dt.index_id AND dt.avg_fragmentation_in_percent>10
AND dt.avg_page_space_used_in_percent<75 ORDER BY avg_fragmentation_in_percent DESC
--索引碎片信息
--使用下面的規則分析結果 你就可以找出哪裡發生了索引碎片
--1)ExternalFragmentation的值>10表示對應的索引發生了外部碎片;
--2)InternalFragmentation的值<75表示對應的索引發生了內部碎片
--如何整理索引碎片
--有兩種整理索引碎片的方法
--1)重組有碎片的索引執行下面的命令
ALTER INDEX ALL ON TableName REORGANIZE
--2)重建索引執行下面的命令
ALTER INDEX ALL ON TableName REBUILD WITH (FILLFACTOR=90,ONLINE=ON)
--也可以使用索引名代替這里的ALL關鍵字重組或重建單個索引 也可以使用SQL Server管理工作台進行索引碎片的整理
使用SQL Server管理工作台整理索引碎片
什麼時候用重組什麼時候用重建呢?
當對應索引的外部碎片值介於10-15之間內部碎片值介於60-75之間時使用重組其它情況就應該使用重建
值得注意的是重建索引時索引對應的表會被鎖定但重組不會鎖表因此在生產系統中對大表重建索引要慎重因為在大表上創建索引可能會花幾個小時
幸運的是從SQL Server 2005開始微軟提出了一個解決辦法在重建索引時將ONLINE選項設置為ON這樣可以保證重建索引時表仍然可以正常使用
雖然索引可以提高查詢速度但如果你的資料庫是一個事務型資料庫大多數時候都是更新操作更新數據也就意味著要更新索引
這個時候就要兼顧查詢和更新操作了因為在OLTP資料庫表上創建過多的索引會降低整體資料庫性能
如果你的資料庫是事務型的平均每個表上不能超過5個索引 如果你的資料庫是數據倉庫型平均每個表可以創建10個索引都沒問題
㈧ sqlserver索引碎片怎麼避免
毫無疑問,給表添加索引是有好處的,你要做的大部分工作就是維護索引,在數據更改期間索引可能產生碎片,所以一些維護是必要的。碎片可能是你查詢產生性能問題的來源。
那麼到底什麼是索引碎片呢?索引碎片實際上有2種形式:外部碎片和內部碎片。不管哪種碎片基本上都會影響索引內頁的使用。這也許是因為頁的邏輯順序錯誤(即外部碎片)或每頁存儲的數據量少於數據頁的容量(內部錯誤)。無論索引產生了哪種類型的碎片,你都會因為它而面臨查詢的性能問題。
外部碎片
當 索引頁不在邏輯順序上時就會產生外部碎片。索引創建時,索引鍵按照邏輯順序放在一組索引頁上。當新數據插入索引時,新的鍵可能放在存在的鍵之間。為了讓新 的鍵按照正確的順序插入,可能會創建新的索引頁來存儲需要移動的那些存在的鍵。這些新的索引頁通常物理上不會和那些被移動的鍵原來所在的頁相鄰。創建新頁 的過程會引起索引頁偏離邏輯順序。
下面的例子將比實際的言論更加清晰的解釋這個概念。
假定在任何另外的數據插入你的表之前存在索引上的結構如下
(註:下面圖片里應該是7和8,原文里是6和8):
INSERT語句往索引里添加新的數據,假定添加的是5。INSERT將引起新頁創建,為了給5在原來的頁上留出空間,7和8被移到了新頁上。這個創建將引起索引頁偏離邏輯順序。
在有特定搜索或者返回無序結果集的查詢的情況下,偏離順序的索引頁不會引起問題。對於返回有序結果集的查詢,搜索那些無序的索引頁需要進行額外的處理。有序結果集的例子如查詢返回4到10之間的記錄。為了返回7和8,查詢不得不進行額外的頁切換。雖然一個額外的頁切換在一個長時間運行里是無關緊要的,然而想像一下一個有好幾百頁偏離順序的非常大的表的情形。
內部碎片
當索引頁沒有用到最大量時就產生了內部碎片。雖然在一個有頻繁數據插入的應用程序里這也許有幫助,然而設置一個fill factor(填充因子)會在索引頁上留下空間,伺服器內部碎片會導致索引尺寸增加,從而在返回需要的數據時要執行額外的讀操作。這些額外的讀操作會降低查詢的性能。
怎樣確定索引是否有碎片?
SQLServer提供了一個資料庫命令――DBCC SHOWCONTIG――來確定一個指定的表或索引是否有碎片。
DBCC SHOWCONTIG
資料庫平台命令,用來顯示指定的表的數據和索引的碎片信息。
DBCC SHOWCONTIG 許可權默認授予 sysadmin固定伺服器角色或 db_owner 和 db_ddladmin固定資料庫角色的成員以及表的所有者且不可轉讓。
語法(SQLServer2000)
DBCC SHOWCONTIG
[ ( { table_name | table_id| view_name | view_id }
[ , index_name | index_id ]
)
]
[ WITH { ALL_INDEXES
| FAST [ , ALL_INDEXES ]
| TABLERESULTS [ , { ALL_INDEXES } ]
[ , { FAST | ALL_LEVELS } ]
}
]
語法(SQLServer7.0)
DBCC SHOWCONTIG
[ ( table_id [,index_id ]
)
]
示例:
顯示資料庫里所有索引的碎片信息
SET NOCOUNT ON
USE pubs
DBCC SHOWCONTIG WITH ALL_INDEXES
GO
顯示指定表的所有索引的碎片信息
SET NOCOUNT ONUSE pubs
DBCC SHOWCONTIG (authors) WITH ALL_INDEXES
GO
顯示指定索引的碎片信息
SET NOCOUNT ON
USE pubs
DBCC SHOWCONTIG (authors,aunmind)
GO
結果集
DBCC SHOWCONTIG將返回掃描頁數、掃描擴展盤區數、遍歷索引或表的頁時,DBCC 語句從一個擴展盤區移動到其它擴展盤區的次數、每個擴展盤區的頁數、掃描密度(最佳值是指在一切都連續地鏈接的情況下,擴展盤區更改的理想數目)。
DBCC SHOWCONTIG 正在掃描 'authors' 表...
表: 'authors'(1977058079);
索引 ID: 1,資料庫 ID: 5
已執行 TABLE 級別的掃描。
- 掃描頁數.....................................: 1
- 掃描擴展盤區數...............................: 1
- 擴展盤區開關數...............................: 0
- 每個擴展盤區上的平均頁數.....................: 1.0
- 掃描密度[最佳值:實際值]....................: 100.00%[1:1]
- 邏輯掃描碎片.................................: 0.00%
- 擴展盤區掃描碎片.............................: 0.00%
- 每頁上的平均可用位元組數.......................: 6010.0
- 平均頁密度(完整)...........................: 25.75%
DBCC 執行完畢。如果 DBCC 輸出了錯誤信息,請與系統管理員聯系。
尋找什麼
掃描頁數:如果你知道行的近似尺寸和表或索引里的行數,那麼你可以估計出索引里的頁數。看看掃描頁數,如果明顯比你估計的頁數要高,說明存在內部碎片。
掃描擴展盤區數:用掃描頁數除以8,四捨五入到下一個最高值。該值應該和DBCC SHOWCONTIG返回的掃描擴展盤區數一致。如果DBCC SHOWCONTIG返回的數高,說明存在外部碎片。碎片的嚴重程度依賴於剛才顯示的值比估計值高多少。
擴展盤區開關數:該數應該等於掃描擴展盤區數減1。高了則說明有外部碎片。
每個擴展盤區上的平均頁數:該數是掃描頁數除以掃描擴展盤區數,一般是8。小於8說明有外部碎片。
掃描密度[最佳值:實際值]:DBCC SHOWCONTIG返回最有用的一個百分比。這是擴展盤區的最佳值和實際值的比率。該百分比應該盡可能靠近100%。低了則說明有外部碎片。
邏輯掃描碎片:無序頁的百分比。該百分比應該在0%到10%之間,高了則說明有外部碎片。
擴展盤區掃描碎片:無序擴展盤區在掃描索引葉級頁中所佔的百分比。該百分比應該是0%,高了則說明有外部碎片。
每頁上的平均可用位元組數:所掃描的頁上的平均可用位元組數。越高說明有內部碎片,不過在你用這個數字決定是否有內部碎片之前,應該考慮fill factor(填充因子)。
平均頁密度(完整):每頁上的平均可用位元組數的百分比的相反數。低的百分比說明有內部碎片。
備注
DBCC SHOWCONTIG實際上僅對那些大表有用。小表顯示的結果根本不符合正常標准,因為他們也許沒有由多於8個的頁面組成。你在查看小表上執行DBCC SHOWCONTIG的結果時應該忽略一些結果。在處理小表時只需關心擴展盤區開關數、邏輯掃描碎片、每頁上的平均可用位元組數、平均頁密度(完整)。
DBCC SHOWCONTIG默認輸出的結果是:掃描頁數、掃描擴展盤區數、擴展盤區開關數、每個擴展盤區上的平均頁數、掃描密度[最佳值:實際值]、邏輯掃描碎片、擴展盤區掃描碎片、每頁上的平均可用位元組數、平均頁密度(完整)。可以用FAST和TABLERESULTS選項來控制這個輸出結果。
FAST選項指定執行索引的快速掃描,輸出結果是最小的,該選項不讀索引的葉或數據頁且只返回掃描頁數、掃描擴展盤區數、掃描密度[最佳值:實際值]、邏輯掃描碎片。
TABLERESULTS選項將用行集的形式顯示信息,將返回擴展盤區開關數、掃描密度[最佳值:實際值]、邏輯掃描碎片、擴展盤區掃描碎片、每頁上的平均可用位元組數、平均頁密度(完整)。
如果既指定FAST選項又指定TABLERESULTS選項,那麼將返回對象名、對象ID、索引名、索引ID,頁數、擴展盤區開關數、掃描密度[最佳值:實際值]和邏輯掃描碎片。
ALL_INDEXES選項將顯示指定表和試圖的所有索引的結果,即使指定了一個索引。
ALL_LEVELS選項指定是否為所處理的每個索引的每個級別產生輸出(默認只輸出索引的頁級或表數據級的結果),並且只能與 TABLERESULTS 選項一起使用。
解決碎片問題
一旦你確定表或索引有碎片問題,那麼你有4個選擇去解決那些問題:
刪除並重建索引
使用DROP_EXISTING子句重建索引
執行DBCC DBREINDEX
執行DBCC INDEXDEFRAG
盡管每一個技術都能達到你整理索引碎片的最終目的,但各有各的優缺點。
刪除並重建索引
用DROP INDEX和CREATE INDEX或ALTER TABLE來 刪除並重建索引有些缺陷包括在刪除重建期間索引會消失。在索引刪除重建時,對於查詢它不在可用,查詢性能也許會受到明顯的影響,直到重建索引為止。另一個 潛在的缺陷是當都請求索引的時候會引起阻塞,直到重建索引為止。通過其他的處理也能解決阻塞,就是索引被使用的時候不刪除索引。另一個主要的缺陷是在用DROP INDEX和CREATE INDEX重建聚集索引時會引起非聚集索引重建兩次。刪除聚集索引時非聚集索引的行指針會指向數據堆,聚集索引重建時非聚集索引的行指針又會指回聚集索引的行位置。
刪除並重建索引的確有一個好處就是通過重新排序索引頁,使索引頁緊湊並刪除不需要的索引頁來完全重建索引。你也許需要考慮那些內部和外部碎片都很高的情況下才使用,以使那些索引回到它們應該在的位置。
使用DROP_EXISTING子句重建索引
為了避免在重建聚集索引時表上的非聚集索引重建兩次,可以使用帶DROP_EXISTING子句的CREATE INDEX語句。這個子句會保留聚集索引鍵值,以避免非聚集索引重建兩次。和刪除並重建索引一樣,該方法也可能會引起阻塞和索引消失的問題。該方法的另一個缺陷是也強迫你去分別發現和修復表上的每一個索引。 除了和上一個方法一樣的好處之外,該方法的好處是不必重建非聚集索引兩次。這樣可以對那些帶約束的索引提供正確的索引定義以符合約束的要求。 執行DBCC DBREINDEX DBCC DBREINDEX類似於第二種方法,但它物理地重建索引,允許SQLServer給索引分配新頁來減少內部和外部碎片。DBCC DBREINDEX也能動態的重建帶約束的索引,不象第二種方法。 DBCC DBREINDEX的缺陷是會遇到或引起阻塞問題。DBCC DBREINDEX是作為一個事務來運行的,所以如果在完成之前中斷了,那麼你會丟失所有已經執行過的碎片。 執行DBCC INDEXDEFRAG DBCC INDEXDEFRAG(在SQLServer2000中可用)按照索引鍵的邏輯順序,通過重新整理索引里存在的葉頁來減少外部碎片,通過壓縮索引頁里的行然後刪除那些由此產生的不需要的頁來減少內部碎片。它不會遇到阻塞問題但它的結果沒有其他幾個方法徹底。這是因為DBCC INDEXDEFRAG跳過了鎖定的頁且不使用任何新頁來重新排序索引。如果索引的碎片數量大的話你也許會發現DBCC INDEXDEFRAG比重建索引花費的時間更長。DBCC INDEXDEFRAG比其他方法的確有好處的是在其他過程訪問索引時也能進行碎片整理,不會引起其他方法的阻塞問題。
㈨ mysql 如何去整理表數據,碎片整理
MySQL 的碎片是 MySQL 運維過程中比較常見的問題,碎片的存在十分影響資料庫的性能,本文將對 MySQL 碎片進行一次講解。
判斷方法:
MySQL 的碎片是否產生,通過查看
show table status from table_nameG;
這個命令中 Data_free 欄位,如果該欄位不為 0,則產生了數據碎片。
產生的原因:
1. 經常進行 delete 操作
經常進行 delete 操作,產生空白空間,如果進行新的插入操作,MySQL將嘗試利用這些留空的區域,但仍然無法將其徹底佔用,久而久之就產生了碎片;
演示:
創建一張表,往裡面插入數據,進行一個帶有 where 條件或者 limit 的 delete 操作,刪除前後對比一下 Data_free 的變化。
刪除前:
Data_free 不為 0,說明有碎片;
2. update 更新
update 更新可變長度的欄位(例如 varchar 類型),將長的字元串更新成短的。之前存儲的內容長,後來存儲是短的,即使後來插入新數據,那麼有一些空白區域還是沒能有效利用的。
演示:
創建一張表,往裡面插入一條數據,進行一個 update 操作,前後對比一下 Data_free 的變化。
CREATE TABLE `t1` ( `k` varchar(3000) DEFAULT NULL ) ENGINE=MyISAM DEFAULT CHARSET=utf8;
更新語句:update t1 set k='aaa';
更新前長度:223 Data_free:0
更新後長度:3 Data_free:204
Data_free 不為 0,說明有碎片;
產生影響:
1. 由於碎片空間是不連續的,導致這些空間不能充分被利用;
2. 由於碎片的存在,導致資料庫的磁碟 I/O 操作變成離散隨機讀寫,加重了磁碟 I/O 的負擔。
清理辦法:
MyISAM:optimize table 表名;(OPTIMIZE 可以整理數據文件,並重排索引)
Innodb:
select count(*) from test.twitter_11;
1. ALTER TABLE tablename ENGINE=InnoDB;(重建表存儲引擎,重新組織數據)
2. 進行一次數據的導入導出
碎片清理的性能對比:
引用我之前一個生產庫的數據,對比一下清理前後的差異。
SQL執行速度:
修改前:1 row in set (7.37 sec)
修改後:1 row in set (1.28 sec)
結論:
通過對比,可以看到碎片清理前後,節省了很多空間,SQL執行效率更快。所以,在日常運維工作中,應對碎片進行定期清理,保證資料庫有穩定的性能。
㈩ 請教SQL里怎樣使用碎片整理
SQLServer提供了一個資料庫命令——DBCC SHOWCONTIG——來確定一個指定的表或索引是否有碎片。
示例:
顯示資料庫里所有索引的碎片信息
DBCC SHOWCONTIG WITH ALL_INDEXES
顯示指定表的所有索引的碎片信息
DBCC SHOWCONTIG (authors) WITH ALL_INDEXES
顯示指定索引的碎片信息
DBCC SHOWCONTIG (authors,aunmind)
DBCC 執行結果:
掃描頁數:如果你知道行的近似尺寸和表或索引里的行數,那麼你可以估計出索引里的頁數。看看掃描頁數,如果明顯比你估計的頁數要高,說明存在內部碎片。
掃描擴展盤區數:用掃描頁數除以8,四捨五入到下一個最高值。該值應該和DBCC SHOWCONTIG返回的掃描擴展盤區數一致。如果DBCC SHOWCONTIG返回的數高,說明存在外部碎片。碎片的嚴重程度依賴於剛才顯示的值比估計值高多少。
擴展盤區開關數:該數應該等於掃描擴展盤區數減1。高了則說明有外部碎片。
每個擴展盤區上的平均頁數:該數是掃描頁數除以掃描擴展盤區數,一般是8。小於8說明有外部碎片。
掃描密度[最佳值:實際值]:DBCC SHOWCONTIG返回最有用的一個百分比。這是擴展盤區的最佳值和實際值的比率。該百分比應該盡可能靠近100%。低了則說明有外部碎片。
邏輯掃描碎片:無序頁的百分比。該百分比應該在0%到10%之間,高了則說明有外部碎片。
擴展盤區掃描碎片:無序擴展盤區在掃描索引葉級頁中所佔的百分比。該百分比應該是0%,高了則說明有外部碎片。
每頁上的平均可用位元組數:所掃描的頁上的平均可用位元組數。越高說明有內部碎片,不過在你用這個數字決定是否有內部碎片之前,應該考慮fill factor(填充因子)。
平均頁密度(完整):每頁上的平均可用位元組數的百分比的相反數。低的百分比說明有內部碎片。
解決碎片問題 :
1. 刪除並重建索引
2. 使用DROP_EXISTING子句重建索引
3. 執行DBCC DBREINDEX
4. 執行DBCC INDEXDEFRAG
刪除並重建索引 :
用DROP INDEX和CREATE INDEX或ALTER TABLE來刪除並重建索引有些缺陷包括在刪除重建期間索引會消失。在索引刪除重建時,對於查詢它不在可用,查詢性能也許會受到明顯的影響,直到重建索引為止。另一個潛在的缺陷是當都請求索引的時候會引起阻塞,直到重建索引為止。通過其他的處理也能解決阻塞,就是索引被使用的時候不刪除索引。另一個主要的缺陷是在用DROP INDEX和CREATE INDEX重建聚集索引時會引起非聚集索引重建兩次。刪除聚集索引時非聚集索引的行指針會指向數據堆,聚集索引重建時非聚集索引的行指針又會指回聚集索引的行位置。
刪除並重建索引的確有一個好處就是通過重新排序索引頁,使索引頁緊湊並刪除不需要的索引頁來完全重建索引。你也許需要考慮那些內部和外部碎片都很高的情況下才使用,以使那些索引回到它們應該在的位置。
使用DROP_EXISTING子句重建索引 :
為了避免在重建聚集索引時表上的非聚集索引重建兩次,可以使用帶DROP_EXISTING子句的CREATE INDEX語句。這個子句會保留聚集索引鍵值,以避免非聚集索引重建兩次。和刪除並重建索引一樣,該方法也可能會引起阻塞和索引消失的問題。該方法的另一個缺陷是也強迫你去分別發現和修復表上的每一個索引。
除了和上一個方法一樣的好處之外,該方法的好處是不必重建非聚集索引兩次。這樣可以對那些帶約束的索引提供正確的索引定義以符合約束的要求。
執行DBCC DBREINDEX :
DBCC DBREINDEX類似於第二種方法,但它物理地重建索引,允許SQLServer給索引分配新頁來減少內部和外部碎片。DBCC DBREINDEX也能動態的重建帶約束的索引,不象第二種方法。
DBCC DBREINDEX的缺陷是會遇到或引起阻塞問題。DBCC DBREINDEX是作為一個事務來運行的,所以如果在完成之前中斷了,那麼你會丟失所有已經執行過的碎片。
執行DBCC INDEXDEFRAG :
DBCC INDEXDEFRAG(在SQLServer2000中可用)按照索引鍵的邏輯順序,通過重新整理索引里存在的葉頁來減少外部碎片,通過壓縮索引頁里的行然後刪除那些由此產生的不需要的頁來減少內部碎片。它不會遇到阻塞問題但它的結果沒有其他幾個方法徹底。這是因為DBCC INDEXDEFRAG跳過了鎖定的頁且不使用任何新頁來重新排序索引。如果索引的碎片數量大的話你也許會發現DBCC INDEXDEFRAG比重建索引花費的時間更長。DBCC INDEXDEFRAG比其他方法的確有好處的是在其他過程訪問索引時也能進行碎片整理,不會引起其他方法的阻塞問題。