1. 程式人生 > >重建 SQLServer 索引的重要性!

重建 SQLServer 索引的重要性!

大多數SQL Server表需要索引來提高資料的訪問速度,如果沒有索引,SQL Server要進行表格掃描讀取表中的每一個記錄才能找到索要的資料。索引可以分為簇索引和非簇索引,簇索引通過重排表中的資料來提高資料的訪問速度,而非簇索引則通過維護表中的資料指標來提高資料的索引。

索引的體系結構:

為什麼要不斷的維護表的索引?首先,簡單介紹一下索引的體系結構。SQL Server在硬碟中用8KB頁面在資料庫檔案記憶體放資料。預設情況下這些頁面及其包含的資料是無組織的。為了使混亂變為有序,就要生成索引。生成索引後,就有了索引頁和資料頁,資料頁儲存使用者寫入的資料資訊。索引頁存放用於檢索列的資料值清單(關鍵字)和索引表中該值所在紀錄的地址指標。索引分為簇索引和非簇索引,簇索引實質上是將表中的資料排序,就好像是字典的索引目錄。非簇索引不對資料排序,它只儲存了資料的指標地址。向一個帶簇索引的表中插入資料,當資料頁達到100%時,由於頁面沒有空間插入新的的紀錄,這時就會發生分頁,SQL Server 將大約一半的資料從滿頁中移到空頁中,從而生成兩個半的滿頁。這樣就有大量的資料空間。簇索引是雙向連結串列,在每一頁的頭部儲存了前一頁、後一頁地址以及分頁後資料移動的地址,由於新頁可能在資料庫檔案中的任何地方,因此頁面的連結不一定指向磁碟的下一個物理頁,連結可能指向了另一個區域,這就形成了分塊,從而減慢了系統的速度。對於帶簇索引和非簇索引的表來說,非簇索引的關鍵字是指向簇索引的,而不是指向資料頁的本身。

為了克服資料分塊帶來的負面影響,需要重構表的索引,這是非常費時的,因此只能在需要時進行。可以通過DBCC SHOWCONTIG來確定是否需要重構表的索引。下面舉例來說明DBCC SHOWCONTIG和DBCC REDBINDEX的使用方法。以SQL Server自帶的northwind資料作為例子

 帶開SQL Server的Query analyzer輸入命令:

use pubs

declare @table_id int

set @table_id=object_id('tbldlvinfoback')

dbcc showcontig(@table_id)

這個命令顯示pubs資料庫中的tbldlvinfoback表的分塊情況,結果如下:

DBCC SHOWCONTIG 正在掃描 'tblDlvInfoback' 表...

表: 'tblDlvInfoback'(1797581442);索引 ID: 0,資料庫 ID: 5

已執行 TABLE 級別的掃描。

- 掃描頁數.....................................: 197214

- 掃描擴充套件盤區數...............................: 24659

- 擴充套件盤區開關數...............................: 24658

- 每個擴充套件盤區上的平均頁數.....................: 8.0

- 掃描密度[最佳值:實際值]....................: 99.97%[24652:24659]

- 擴充套件盤區掃描碎片.............................: 15.46%

- 每頁上的平均可用位元組數.......................: 374.6

- 平均頁密度(完整)...........................: 95.37%

DBCC 執行完畢。如果 DBCC 輸出了錯誤資訊,請與系統管理員聯絡。

通過分析這些結果可以知道該表的索引是否需要重構。表1.1描述了每一行的意義描述

Pages Scanned                    表或索引中的長頁數

Extents Scanned                  表或索引中的長區頁數

Extent Switches                 DBCC遍歷頁時從一個區域到另

一個區域的次數

Avg. Pages per Extent                       相關區域中的頁數

Scan Density                                    Best Count是連續連結時的理想區

[Best Count:Actual Count]                域改變數,Actual Count是實際區

域改變數,Scan Density為100%

表示沒有分塊。

Logical Scan Fragmentation            掃描索引頁中失序頁的百分比

Extent Scan Fragmentation               不實際相鄰和包含鏈路中所有鏈

接頁的區域數

Avg. Bytes Free per Page                  掃描頁面中平均自由位元組數

Avg. Page Density (full)                     平均頁密度,表示頁有多滿

從上面命令的執行結果可以看的出來,Best count為3 而Actual Count為5這表明orders表有分塊需要重構表索引。下面通過DBCC DBREINDEX來重構表的簇索引。

同樣在Query Analyzer中輸入命令:

use northwind

dbcc dbreindex('northwind.dbo.orders',pk_orders,90)

執行結果

DBCC execution completed. If DBCC printed error messages, contact your system administrator.

Dbcc dbreindex引數說明第一個引數為要重構的表明。第二個引數為需要重構的索引表識,‘’表示所有的索引。第三個引數為頁的填充因子,填充因子越大,頁越滿。

然後再用DBCC SHOWCONTIG檢視重構簇索引後的結果:

use northwind

declare @table_id int

t @table_id=object_id('orders')

dbcc showcontig(@table_id)

返回結果如下:

DBCC SHOWCONTIG scanning 'Orders' table...

Table: 'Orders' (21575115); index ID: 1, database ID: 6

TABLE level scan performed.

- Pages Scanned................................: 22

- Extents Scanned..............................: 3

- Extent Switches..............................: 2

- Avg. Pages per Extent........................: 7.3

- Scan Density [Best Count:Actual Count].......: 100.00% [3:3]

- Logical Scan Fragmentation ..................: 0.00%

- Extent Scan Fragmentation ...................: 33.33%

- Avg. Bytes Free per Page.....................: 869.2

- Avg. Page Density (full).....................: 89.26%

DBCC execution completed. If DBCC printed error messages, contact your system administrator.

通過結果我們可以看到Scan Denity100%表沒有分塊不需要重構表索引了。如果重構表的簇索引Scan Denity還小於100%的話可以重構表的全部索引。命令如下

--use northwind

--dbcc dbreindex('northwind.dbo.orders',’’,90)

使用作業定時重構索引:

如果你的資料庫訪問非常頻繁的話,非常容易出現數據分塊的現象,因此你可以利用作業來幫你在系統相對空閒的時候重構你的索引。

為什麼要不斷的維護表的索引?首先,簡單介紹一下索引的體系結構。SQL Server在硬碟中用8KB頁面在資料庫檔案記憶體放資料。預設情況下這些頁面及其包含的資料是無組織的。為了使混亂變為有序,就要生成索引。生成索引後,就有了索引頁和資料頁,資料頁儲存使用者寫入的資料資訊。索引頁存放用於檢索列的資料值清單(關鍵字)和索引表中該值所在紀錄的地址指標。索引分為簇索引和非簇索引,簇索引實質上是將表中的資料排序,就好像是字典的索引目錄。非簇索引不對資料排序,它只儲存了資料的指標地址。向一個帶簇索引的表中插入資料,當資料頁達到100%時,由於頁面沒有空間插入新的的紀錄,這時就會發生分頁,SQL Server 將大約一半的資料從滿頁中移到空頁中,從而生成兩個半的滿頁。這樣就有大量的資料空間。簇索引是雙向連結串列,在每一頁的頭部儲存了前一頁、後一頁地址以及分頁後資料移動的地址,由於新頁可能在資料庫檔案中的任何地方,因此頁面的連結不一定指向磁碟的下一個物理頁,連結可能指向了另一個區域,這就形成了分塊,從而減慢了系統的速度。對於帶簇索引和非簇索引的表來說,非簇索引的關鍵字是指向簇索引的,而不是指向資料頁的本身。

為了克服資料分塊帶來的負面影響,需要重構表的索引,這是非常費時的,因此只能在需要時進行。可以通過DBCC SHOWCONTIG來確定是否需要重構表的索引。下面舉例來說明DBCC SHOWCONTIG和DBCC REDBINDEX的使用方法。以SQL Server自帶的northwind資料作為例子

 帶開SQL Server的Query analyzer輸入命令:

use pubs

declare @table_id int

set @table_id=object_id('tbldlvinfoback')

dbcc showcontig(@table_id)

這個命令顯示pubs資料庫中的tbldlvinfoback表的分塊情況,結果如下:

DBCC SHOWCONTIG 正在掃描 'tblDlvInfoback' 表...

表: 'tblDlvInfoback'(1797581442);索引 ID: 0,資料庫 ID: 5

已執行 TABLE 級別的掃描。

- 掃描頁數.....................................: 197214

- 掃描擴充套件盤區數...............................: 24659

- 擴充套件盤區開關數...............................: 24658

- 每個擴充套件盤區上的平均頁數.....................: 8.0

- 掃描密度[最佳值:實際值]....................: 99.97%[24652:24659]

- 擴充套件盤區掃描碎片.............................: 15.46%

- 每頁上的平均可用位元組數.......................: 374.6

- 平均頁密度(完整)...........................: 95.37%

DBCC 執行完畢。如果 DBCC 輸出了錯誤資訊,請與系統管理員聯絡。

通過分析這些結果可以知道該表的索引是否需要重構。表1.1描述了每一行的意義描述

Pages Scanned                    表或索引中的長頁數

Extents Scanned                  表或索引中的長區頁數

Extent Switches                 DBCC遍歷頁時從一個區域到另

一個區域的次數

Avg. Pages per Extent                       相關區域中的頁數

Scan Density                                    Best Count是連續連結時的理想

[Best Count:Actual Count]                域改變數,Actual Count是實際區

域改變數,Scan Density為100%

表示沒有分塊。

Logical Scan Fragmentation            掃描索引頁中失序頁的百分比

Extent Scan Fragmentation               不實際相鄰和包含鏈路中所有鏈

接頁的區域數

Avg. Bytes Free per Page                  掃描頁面中平均自由位元組數

Avg. Page Density (full)                     平均頁密度,表示頁有多滿

從上面命令的執行結果可以看的出來,Best count為3 而Actual Count為5這表明orders表有分塊需要重構表索引。下面通過DBCC DBREINDEX來重構表的簇索引。

同樣在Query Analyzer中輸入命令:

use northwind

dbcc dbreindex('northwind.dbo.orders',pk_orders,90)

執行結果

DBCC execution completed. If DBCC printed error messages, contact your system administrator.

Dbcc dbreindex引數說明第一個引數為要重構的表明。第二個引數為需要重構的索引表識,‘’表示所有的索引。第三個引數為頁的填充因子,填充因子越大,頁越滿。

然後再用DBCC SHOWCONTIG檢視重構簇索引後的結果:

use northwind

declare @table_id int

set @table_id=object_id('orders')

dbcc showcontig(@table_id)

返回結果如下:

DBCC SHOWCONTIG scanning 'Orders' table...

Table: 'Orders' (21575115); index ID: 1, database ID: 6

TABLE level scan performed.

- Pages Scanned................................: 22

- Extents Scanned..............................: 3

- Extent Switches..............................: 2

- Avg. Pages per Extent........................: 7.3

- Scan Density [Best Count:Actual Count].......: 100.00% [3:3]

- Logical Scan Fragmentation ..................: 0.00%

- Extent Scan Fragmentation ...................: 33.33%

- Avg. Bytes Free per Page.....................: 869.2

- Avg. Page Density (full).....................: 89.26%

DBCC execution completed. If DBCC printed error messages, contact your system administrator.

通過結果我們可以看到Scan Denity100%表沒有分塊不需要重構表索引了。如果重構表的簇索引Scan Denity還小於100%的話可以重構表的全部索引。命令如下:

--use northwind

--dbcc dbreindex('northwind.dbo.orders',’’,90)

使用作業定時重構索引:

如果你的資料庫訪問非常頻繁的話,非常容易出現數據分塊的現象,因此你可以利用作業來幫你在系統相對空閒的時候重構你的索引 

 

相關推薦

重建 SQLServer 索引重要性!

大多數SQL Server表需要索引來提高資料的訪問速度,如果沒有索引,SQL Server要進行表格掃描讀取表中的每一個記錄才能找到索要的資料。索引可以分為簇索引和非簇索引,簇索引通過重排表中的資料來提高資料的訪問速度,而非簇索引則通過維護表中的資料指標來提高資料的索引。

sqlserver重建(rebuild)索引可以提高查詢速度

當隨著表的資料量不斷增長,很多儲存的資料進行了不適當的跨頁(sqlserver中儲存的最小單位是頁,頁是不不可再分的),會產生很多索引的碎片。這時候需要重建索引來提高查詢效能。 如何檢視索引的使用情況: SELECT index_type_desc,alloc_unit_t

SQLServer 索引重建儲存過程

SQLServer建議索引碎片在5%--30%之間用重新組織索引(REORGANIZE),超過30%的重新生成索引(REBUILD)生成索引可以線上也可以離線(ONLINE = OFF):離線索引不能訪問。USE [zws]GO/****** Object:  StoredP

數據結構~Sqlserver索引使用的B樹

vsa pvs lol kff avs elk bin nmf eth1 B樹相關概念 在B-樹中查找給定關鍵字的方法是,首先把根結點取來,在根結點所包含的關鍵字K1,…,Kn查找給定的關鍵字(可用順序查找或二分查找法),若找到等於給定值的關鍵字,則查找成功;否則,一定可以

SqlServer索引的原理與應用

文件 char date 存儲空間 字段 文件頭 其它 要求 混合 索引的概念 索引的用途:我們對數據查詢及處理速度已成為衡量應用系統成敗的標準,而采用索引來加快數據處理速度通常是最普遍采用的優化方法。 索引是什麽:數據庫中的索引類似於一本書的目錄,在一本書中使用目錄可以

sqlServer-索引

減少 數據檢索 添加 企業版 頁碼 選擇 數據庫 關系型數據庫 group by 在關系型數據庫中,索引是一種單獨的,物理的對數據庫表中一列或多列的值進行排序的一種存儲結構。 索引的作用相當於圖書的目錄,可以根據目錄中的頁碼快速找到所需的內容。 當表中有大量記錄時,若要對表

iOS - Mac 重建 Spotlight 索引

使用 是把 情況下 用戶 分享 設置 替換 想要 enabled 前言 最近發現很多 mac 用戶反映自己的 mac 系統顯示內存占用高達 200 多 Gb,可是實際上自己下載的應用程序根本沒那麽多,使用專業的內存掃描工具掃的結果跟系統本身顯示的完全不一樣。那麽出現這個問

SqlServer 索引和視圖

alt 主鍵 www from 字符 重新 視圖 target 修改 Ø 索引 1、 什麽是索引 索引就是數據表中數據和相應的存儲位置的列表,利用索引可以提高在表或視圖中的查找數據的速度。 2、 索引分類

sqlserver索引

2012: https://docs.microsoft.com/zh-cn/previous-versions/sql/sql-server-2012/ms175049(v%3Dsql.110) 2017: https://docs.microsoft.com/zh-cn/sql/

SqlServer索引的建立、檢視、刪除

1、索引的建立 #1使用企業管理器建立 啟動企業管理器–選擇資料庫------選在要建立索引的表------在表的下拉選單中選擇索引—在快捷選單中選擇新建索引– 在新建索引對話方塊中單擊“新增”按鈕,彈出“從列表中選擇列”,在該對話方塊中選擇要新增到索引鍵的表列 單擊確定返回

Oracle如何批量重建資料庫索引

查詢資料庫索引的方法: select * from user_indexes 由此我們可以查到該資料庫下面的所有索引資訊,然後批量生成sql重建語句。 sql的索引重建語句如下: alter index PK_TF_T_SPV_TESTINDEX  rebuild;

技術分享會(二):SQLSERVER索引介紹

SQLSERVER索引介紹 一、SQLSERVER索引型別? 1、聚集索引; 2、非聚集索引; 3、包含索引; 4、列儲存索引; 5、無索引(堆表);   二、如何建立索引? 索引示例: 建表 create table t_test (  &n

orcl索引失效,重建所有索引,或者根據名稱空間重建所有索引

create or replace procedure p_rebuild_all_index    (tablespace_name in varchar2,--這裡是表空間名,如果不改變表空間,可以傳入null    only_unusable in b

SQLSERVER 索引總結

一、儲存結構   在SQL Server中,有許多不同的可用排列規則選項。   二進位制:按字元的數字表示形式排序(ASCII碼中,用數字32表示空格,用68表示字母"D")。因為所有內容都表示為數字,所以處理起來速度最快,遺憾的是,它並不總是如人們所想象,在WHERE子

【MongoDB學習筆記】5:對結果集的操作,建立/檢視/重建/刪除索引

對結果集的操作 在RDBMS中獲得的結果是一張虛擬的表,可以在其上繼續操作。MongoDB中查詢到的結果是一個文件集合,也可以在其上做一些簡單操作。 limit()方法 相當於SQL中的TOP子句,會取結果集中的前指定條文件,使用 結果集.limit(數

SQLServer索引結構及其使用(四)

一、深入淺出理解索引結構二、改善SQL語句三、實現小資料量和海量資料的通用分頁顯示儲存過程 聚集索引的重要性和如何選擇聚集索引  在上一節的標題中,筆者寫的是:實現小資料量和海量資料的通用分頁顯示儲存過程。這是因為在將本儲存過程應用於“辦公自動化”系統的實踐中時,筆者發現這第

SQLServer索引迴圈刪除

declare qc_cursor cursor SCROLL OPTIMISTIC Forselect siteName from tb_vhostcheckopen qc_cursordeclare @siteNam

重建資料庫索引等SQL常用語句

壓縮資料庫: --清空日誌 DUMP  TRANSACTION  庫名  WITH  NO_LOG    --截斷事務日誌: BACKUP LOG 庫名 WITH NO_LOG --收縮資料庫 DBCC SHRINKDATABASE(庫名) --收縮

SqlServer索引及優化詳解

(一)深入淺出理解索引結構         實際上,您可以把索引理解為一種特殊的目錄。微軟的SQL SERVER提供了兩種索引:聚集索引(clustered index,也稱聚類索引、簇集索引)和非聚集索引(nonclustered index,也稱非聚類索引、非簇集索

SQLServer索引結構及其使用(二)

改善SQL語句  很多人不知道SQL語句在SQL SERVER中是如何執行的,他們擔心自己所寫的SQL語句會被SQL SERVER誤解。比如: select * from table1 where name='zhangsan' and tID > 10000 和執行