SQL Server 性能優化實戰系列(二)
SQL Server datetime數據類型設計、優化誤區
一、場景
在SQL Server 2005中,有一個表TestDatetime,其中Dates這個字段的數據類型是datetime,如果你看到表的記錄如下圖所示,你最先想到的是什麽呢?
(圖1:數據列表)
你看到這些數據,是不是覺得這樣的設計既浪費了存儲空間,又使得這個列的索引增大,查詢起來更慢,你也想使用一些其它的數據類型來代替這個datetime吧?
其實大家都是這麽想的,這個方向是100%正確的,但是在寫這篇文章以前,我進入了兩個誤區:(如果你中了下面的兩個誤區,那麽請你看看這篇文章吧。)
誤區一: 把Dates字段的datetime數據類型換成smalldatetime,這樣數據就由:‘2009-04-09 00:00:00.000’變為‘2009-04-09 00:00:00’,這個看起來沒有減少多少存儲空間哦。
誤區二:把Dates字段的datetime數據類型換成char(10),這樣數據就由:‘2009-04-09 00:00:00.000’變為‘2009-04-09’,這好像能減少很多存儲空間哦。
二、分析
在SQL Server 2005版本中保存日期的數據類型只有兩種:datetime、smalldatetime,但是在SQL Server 2008版本中新增了一些日期數據類型:time、date、smalldatetime、datetime、datetime2、datetimeoffset,其中的date類型就能滿足我們場景中的需求了,如果你幸運的在使用SQL Server 2008的話,那麽恭喜你,請使用date數據類型吧。
但是我就比較可悲一點了,在使用SQL Server 2005的前提下,我進入了誤區一、誤區二。其實這也是因為自己忽略了一下基礎性的東西,如果知道不同數據類型的存儲空間大小,也許就很輕易的避免這樣低級的錯誤了。
其實你查看表TestDatetime中的Dates字段的時候,看到查詢結果中的:“-”、“:”只是用於顯示的,並不是真實保存的時候就這樣格式的。
datetime占用8個字節,前4個字節存儲base date(即1900年1月1日)之前或之後的天數,後4個字節存儲午夜後的毫秒數。值範圍:1753-01-01 到 9999-12-31。
smalldatetime占用4個字節,前2個字節存儲base date(1900年1月1日)之後的天數。後2個字節存儲午夜後的分鐘數。值範圍:1900-01-01 到 2079-06-06。
date占用3個字節,它比smalldatetime的前2個字節多了1字節,所以值的範圍更廣了。值範圍:0001-01-01 到 9999-12-31。
所以,如果你使用char(10)來保存截斷的日期,那麽你的存儲空間反而更大了。
結論: 如果是SQL Server 2005,那麽請你使用smalldatetime吧,數據能節約一半,雖然查詢的時候看起來沒什麽改變;如果你是SQL Server 2008,那麽請你使用date吧,
雖然3個字節跟4個字節沒有多大的差距,但是從設計上和邏輯清晰度上都有很大的提升,而且差距有些時候並不是1個字節的問題,比如當表數據量達到幾個億的時候,還是有差別的,又或者一條記錄可能因為差1個字節就剛剛好給8060字節的頁瓜分,這些都不容忽視的。
三、測試
下面我們就從數據存儲的大小、索引存儲的大小、索引使用時候的速度這幾個方面進行測試:(這裏只測試數據類型:,,數據的內容都是一樣的)
(一) 測試前奏:
- 創建三種數據類型char(10)、datetime、smalldatetime的表;(表結構如下面SQL)
- 插入相同記錄到三個表中;(這裏插入1210000條記錄)
- 為[Dates]字段創建索引;(在創建索引的時候可以設置填充因子為100%)
- 查看索引屬性中的索引碎片信息,查看表數據和索引占用的空間,測試[Dates]字段索引的查詢效率;
CREATE TABLE [dbo].[TestDatetime]( [Id] [int] IDENTITY(1,1) NOT NULL, [Dates] [datetime] NULL, CONSTRAINT [PK_TestDatetime] PRIMARY KEY CLUSTERED ( [Id] ASC )WITH (IGNORE_DUP_KEY = OFF) ON [PRIMARY] ) ON [PRIMARY]
(二) 測試結果:
- 數據存儲大小:
(圖2:數據空間對比)
- 索引存儲信息:
(圖3:char(10))
(圖4:datetime)
(圖5:smalldatetime)
- 索引查詢的情況:
多次執行,SQL Server執行時間為:[char(10)] 大部分在43~59徘徊,偶爾出現小於10的;[datetime]平均在1~2毫秒;[smalldatetime]均在1毫秒;而且大家會發現[smalldatetime]有其它的9次邏輯讀取變為8次了。
--[TestChar10]
SQL Server 分析和編譯時間:
CPU 時間= 0 毫秒,占用時間= 1 毫秒。
(2200 行受影響)
表‘TestChar10‘。掃描計數1,邏輯讀取9 次,物理讀取0 次,預讀0 次,lob 邏輯讀取0 次,lob 物理讀取0 次,lob 預讀0 次。
SQL Server 執行時間:
CPU 時間= 0 毫秒,占用時間= 59 毫秒。
SQL Server 執行時間:
CPU 時間= 0 毫秒,占用時間= 1 毫秒。
--[TestDatetime]
SQL Server 分析和編譯時間:
CPU 時間= 0 毫秒,占用時間= 1 毫秒。
(2200 行受影響)
表‘TestDatetime‘。掃描計數1,邏輯讀取9 次,物理讀取0 次,預讀0 次,lob 邏輯讀取0 次,lob 物理讀取0 次,lob 預讀0 次。
SQL Server 執行時間:
CPU 時間= 0 毫秒,占用時間= 2 毫秒。
SQL Server 執行時間:
CPU 時間= 0 毫秒,占用時間= 1 毫秒。
--[TestSmalldatetime]
SQL Server 分析和編譯時間:
CPU 時間= 0 毫秒,占用時間= 1 毫秒。
(2200 行受影響)
表‘TestSmalldatetime‘。掃描計數1,邏輯讀取8 次,物理讀取0 次,預讀0 次,lob 邏輯讀取0 次,lob 物理讀取0 次,lob 預讀0 次。
SQL Server 執行時間:
CPU 時間= 0 毫秒,占用時間= 1 毫秒。
SQL Server 執行時間:
CPU 時間= 0 毫秒,占用時間= 1 毫秒。
--SQL Server 2008新數據類型 SELECT CAST(‘2007-05-08 12:35:29. 1234567 +12:15‘ AS time(7)) AS ‘time‘ ,CAST(‘2007-05-08 12:35:29. 1234567 +12:15‘ AS date) AS ‘date‘ ,CAST(‘2007-05-08 12:35:29.123‘ AS smalldatetime) AS‘smalldatetime‘ ,CAST(‘2007-05-08 12:35:29.123‘ AS datetime) AS ‘datetime‘ ,CAST(‘2007-05-08 12:35:29. 1234567 +12:15‘ AS datetime2(7)) AS ‘datetime2‘ ,CAST(‘2007-05-08 12:35:29.1234567 +12:15‘ AS datetimeoffset(7)) AS ‘datetimeoffset‘;
四、參考文獻
日期和時間數據類型及函數 (Transact-SQL)
LEN (Transact-SQL)
DATALENGTH (Transact-SQL)
smalldatetime和datetime存儲
SQL Server 空間換時間的數據庫設計
我們的系統中很常會用到SMS、Email等的發送,在我們的設計中通常會創建一個Tb_outbox表,當產生數據時,插入到Tb_outbox表,由定時器去讀取Tb_outbox的數據進行發送,發送完了再修改Tb_outbox的發送狀態。是的,這就是通常的做法,但是當我們的SMS、Email的發送頻率和數量足夠大的時候,我們的系統就會出現性能、表被鎖等問題。那我們如何是好呢?
下面的設計的一個思想就是如標題所述:空間換時間。就個人而言,我感覺這個描述更加貼切:對象的職責分離,把Insert、Update、Delete等分離在不同的表中。廢話不多說,下面就來看看這個設計圖:
圖:邏輯圖
Tb_NotSent_buffer:待發送短信緩存表(即時清理).
- 該表是為了避免應用過多對Tb_NotSent同時操作產生鎖表情況。
- 主要考慮到產生待發短信的邏輯通常會比較復雜,或者長事務。
- 一次性將已經在buffer表裏的短信insert到Tb_NotSent,這次插入沒有長事務計算,由一條insert from select完成。
- 該表並非一定用到,視乎產生待發短信的邏輯的事務復雜度,和量而定。
Tb_NotSent:待發送的短信(會被定時清理)
- 會將該已經發送的短信的處理結果存儲在jms消息隊列裏。
- 把這些數據從Tb_NotSent copy到Tb_outbox同時,插一條記錄到Tb_Sent.這樣作是為了下一步刪除Tb_NotSent裏已經發送的信息.同時又不因為刪除而鎖Tb_NotSent表(應用使用)
- 使用空間換時間的思想,減少對同一張表(Tb_outbox)的過多操作和過程時間的操作,導致鎖表出現系統瓶頸。
Tb_outbox:存儲歷史記錄的主表,該表需建立在獨立的數據庫。
- 減少備份文件大小,可靈活調整,大大減少備份空間的需求。
- 減少對主數據庫的影響。
Tb_Sent:一個參照表,為刪除Tb_NotSent表做基表
- 已經發送短信(會定時清理),存放已經被網關處理的短信(發送成功或者失敗)。
- 這個表不一定要保存和Tb_NotSent一樣多的字段,也許只要兩個字段,那就是ID值和狀態值。
SQL Server 即時文件初始化
一.本文所涉及的內容(Contents)
- 本文所涉及的內容(Contents)
- 背景(Contexts)
- 基礎知識(Rudimentary Knowledge)
- 實現過程(Process)
- 疑問(Questions)
- 參考文獻(References)
二.背景(Contexts)
數據庫服務器在為表分配初始值的時候很慢,分配初始值40GB的數據文件,花了30多分鐘,一開始的時候一直認為是服務器磁盤的寫入速度太慢造成的,後來經過北京-宋沄劍的提醒:即時文件初始化(Instant File Initialization),設置這一選項之後,速度提升到了19秒,下面將描述這個優化的設置過程。
三.基礎知識(Rudimentary Knowledge)
就數據庫而言,以下幾種情況需要對文件初始化:
1. 創建數據庫;
2. 向現有數據庫中添加文件、日誌或數據;
3. 增大現有文件的大小(包括自動增長操作);
4. 還原數據庫或文件組;
執行上面的操作,操作系統需要用零來填充文件進行初始化。在 SQL Server 中,可以在瞬間對數據文件進行初始化。即時文件初始化將回收已使用的磁盤空間而不使用零來填充該空間。而在向文件中寫入新數據時,磁盤內容將被覆蓋。日誌文件不能立即初始化。
即時文件初始化功能僅在向 SQL Server (MSSQLSERVER) 服務帳戶授予了 SE_MANAGE_VOLUME_NAME 之後才可用。Windows Administrator 組的成員擁有此權限,並可以通過將其他用戶添加到【執行卷維護任務】安全策略中來為其授予此權限。
四.實現過程(Process)
首先運行gpedit.msc,按照Figure1的路徑,找到【執行卷維護任務】,如Figure2所示,默認的情況下它已經設置了Administrators組的;
(Figure1:gpedit.msc)
(Figure2:執行卷維護任務)
接著運行services.msc進入服務設置,查看到SQL Server (MSSQLSERVER)的登陸用戶是【網絡服務】(如Figure3所示),這就是造成初始化40GB文件花費了30多分鐘的原因了,因為【網絡服務】不具備SE_MANAGE_VOLUME_NAME的權限(可查看Administrators組成員);
(Figure3:SQL Server (MSSQLSERVER))
雙擊SQL Server (MSSQLSERVER)服務進入設置,在登陸的選項卡中可以看到帳號是:NT AUTHORITY\NETWORKSERVICE,如Figure4所示。
(Figure4:NT AUTHORITY\NETWORKSERVICE)
直接勾選【本地系統帳號】,在重啟SQL Server (MSSQLSERVER)時遇到了下圖的錯誤:
(Figure5:重啟服務報錯)
查看了相關的系統事件日誌,在SQL Server服務無法使用管理員身份啟動 中解決了(禁用掉SQL Server的協議Shared Memory),設置完之後重啟服務SQL Server (MSSQLSERVER)。
而另外一種思路就是把NT AUTHORITY\NETWORKSERVICE加入到Administrators組中,如Figure6所示。註意:這種方式一樣需要重啟SQL Server (MSSQLSERVER)服務。
(Figure6:Administrators組)
下面我們就來測試下創建40GB文件的性能對比:
--測試即時文件初始化 CREATE DATABASE [TestFileInit] ON PRIMARY ( NAME = N‘TestFileInit‘, FILENAME = N‘F:\DBBackup\TestFileInit.mdf‘ , SIZE = 41943040KB , FILEGROWTH = 1024KB ) LOG ON ( NAME = N‘TestFileInit_log‘, FILENAME = N‘F:\DBBackup\TestFileInit_log.ldf‘ , SIZE = 1024KB , FILEGROWTH = 10%) GO
(Figure7:之前創建時間)
(Figure8:之後創建時間)
註意:禁用即時文件初始化功能,要想讓這個禁用生效,一樣需要重啟SQL Server (MSSQLSERVER)服務。
五.疑問(Questions)
1. 在安裝SQL Server的時候,如何設置會使得SQL Server服務是以【網絡服務】登陸的?
2. 禁用掉SQL Server的協議Shared Memory,這個協議是用來幹嘛的?有什麽作用?
3. 如果把NT AUTHORITY\NETWORKSERVICE加入到Windows組裏面有什麽不安全隱患嘛?
4. 當啟用 TDE 時,即時文件初始化功能不可用。什麽是TDE?
六.參考文獻(References)
數據庫文件初始化
為SQL Server 2005配置Windows即時初始化
Local System/Network Service/Local Service權限詳解
SQL Server 索引中include的魅力(具有包含性列的索引)
開文之前首先要講講幾個概念
【覆蓋查詢】
當索引包含查詢引用的所有列時,它通常稱為“覆蓋查詢”。
【索引覆蓋】
如果返回的數據列就包含於索引的鍵值中,或者包含於索引的鍵值+聚集索引的鍵值中,那麽就不會發生Bookup Lookup,因為找到索引項,就已經找到所需的數據了,沒有必要再到數據行去找了。這種情況,叫做索引覆蓋;
【復合索引】
和復合索引相對的就是單一索引了,就是索引只包含一個字段,所以復合索引就是包含兩個或者多個字段的索引;
【非鍵列】
鍵列就是在索引中所包含的列,當然非鍵列就是該索引之外的列了;
下面就開始今天的主題
【摘要1】
在 SQL Server 2005 中,可以通過將非鍵列添加到非聚集索引的葉級別來擴展非聚集索引的功能。通過包含非鍵列,可以創建覆蓋更多查詢的非聚集索引。這是因為非鍵列具有下列優點:* 它們可以是不允許作為索引鍵列的數據類型。
* 在計算索引鍵列數或索引鍵大小時,數據庫引擎不考慮它們。
當查詢中的所有列都作為鍵列或非鍵列包含在索引中時,帶有包含性非鍵列的索引可以顯著提高查詢性能。這樣可以實現性能提升,因為查詢優化器可以在索引中找到所有列值;不訪問表或聚集索引數據,從而減少磁盤 I/O 操作。
說明:第一:只能是針對非聚集索引;第二:比起復合索引是有性能上的提升的,因為索引的大小變小了;
【摘要2】
鍵列存儲在索引的所有級別中,而非鍵列僅存儲在葉級別中。說明:這就表現為包含與不包含的關系了。有關索引級別的詳細信息,請參閱表組織和索引組織。
【摘要3】
使用包含性列以避免大小限制可以將非鍵列包含在非聚集索引中,以避免超過當前索引大小的限制(最大鍵列數為 16,最大索引鍵大小為 900 字節)。數據庫引擎計算索引鍵列數或索引鍵大小時,不考慮非鍵列。
例如,假設要為 AdventureWorks 示例數據庫的 Document 表中的以下列建立索引:
Title nvarchar(50)
Revision nchar(5)
FileName nvarchar(400)
因為 nchar 和 nvarchar 數據類型的每個字符需要 2 個字節,所以包含這三列的索引將超出 900 字節的大小限制 10 個字節 (455 * 2)。使用 CREATE INDEX 語句的 INCLUDE 子句,可以將索引鍵定義為 (Title, Revision),將 FileName 定義為非鍵列。這樣,索引鍵大小將為 110 個字節 (55 * 2),並且索引仍將包含所需的所有列。下面的語句就創建了這樣的索引。
說明:當你把一個nvarchar(500)的字段設置為主鍵的時候,你就可以看到不能超出900字節的提示了。一般來說我們是不太會做這些操作的,所以那個錯誤提示也是不常見的,也許你可能還見過。
一個數據頁的大小才8k,所以我們合理的設置每個字段的大小,不要浪費太多的空間,這樣對查詢也是有好處的,這個include就比較好的的解決了索引和空間的問題,雖然那些include的數據也會占用空間。
雖然可以設置include,但是也盡量不要使用太多的字段作為索引包含的非鍵列。
【摘要4】
帶有包含性列的索引準則設計帶有包含性列的非聚集索引時,請考慮下列準則:
* 在 CREATE INDEX 語句的 INCLUDE 子句中定義非鍵列。
* 只能對表或索引視圖的非聚集索引定義非鍵列。
* 除 text、ntext 和 image 之外,允許所有數據類型。
* 精確或不精確的確定性計算列都可以是包含性列。有關詳細信息,請參閱為計算列創建索引。
* 與鍵列一樣,只要允許將計算列數據類型作為非鍵索引列,從 image、ntext 和 text 數據類型派生的計算列就可以作為非鍵(包含性)列。
* 不能同時在 INCLUDE 列表和鍵列列表中指定列名。
* INCLUDE 列表中的列名不能重復。
說明:include不能使用在聚集索引中。後面的兩點,這個在實際中很難想象會有這樣的需求要把重復列放到一個索引中。如果有朋友遇到過這樣的需求可以告知一些,不勝感激。那如果有是否可以通過不同的列名(其實保存是同樣的值)來解決這個問題呢??
【摘要5】
列大小準則* 必須至少定義一個鍵列。最大非鍵列數為 1023 列。也就是最大的表列數減 1。
* 索引鍵列(不包括非鍵)必須遵守現有索引大小的限制(最大鍵列數為 16,總索引鍵大小為 900 字節)。
* 所有非鍵列的總大小只受 INCLUDE 子句中所指定列的大小限制;例如,varchar(max) 列限制為 2 GB。
說明:varchar(max)這樣的定義是在2005之後才有的,所以這些數值也是對2005後的版本才生效的。
最大的表列數為:1024
最大非鍵列數為:1023
【摘要6】
修改已定義為包含性列的表列時,要受下列限制:* 除非先刪除索引,否則無法從表中刪除非鍵列。
* 除進行下列更改外,不能對非鍵列進行其他更改:
o 將列的為空性從 NOT NULL 改為 NULL。
o 增加 varchar、nvarchar 或 varbinary 列的長度。
* 這些列修改限制也適用於索引鍵列。
說明:這些細小的東西一直沒有註意過。所以要記錄下來,用來“防身”,呵呵。
【摘要7】
設計建議重新設計索引鍵大小較大的非聚集索引,以便只有用於搜索和查找的列為鍵列。將覆蓋查詢的所有其他列設置為包含性非鍵列。這樣,將具有覆蓋查詢所需的所有列,但索引鍵本身較小,而且效率高。
說明:也就是說把常用的where後面的條件查詢的字段作為索引的鍵列,而需要返回的字段就作為索引包含的非鍵列。
如果where的是兩個或兩個以上的謂詞的話,這個索引就可以創建為復合索引了。以前天真的認為要返回的字段只能通過在復合索引中入這些字段,不管它是否會用來做謂詞。看到這篇文章,才有了豁然開朗的感覺。
【摘要8】
USE AdventureWorks;GO
CREATE INDEX IX_Address_PostalCode
ON Person.Address (PostalCode)
INCLUDE (AddressLine1, AddressLine2, City, StateProvinceID);
說明:這個是使用include的語法,在表的設計中的索引設計中是沒有辦法選擇的;
【摘要9】
性能註意事項避免添加不必要的列。添加過多的索引列(鍵列或非鍵列)會對性能產生下列影響:
* 一頁上能容納的索引行將更少。這樣會使 I/O 增加並降低緩存效率。
* 需要更多的磁盤空間來存儲索引。特別是,將 varchar(max)、nvarchar(max)、varbinary(max) 或 xml 數據類型添加為非鍵索引列會顯著增加磁盤空間要求。這是因為列值被復制到了索引葉級別。因此,它們既駐留在索引中,也駐留在基表中。
* 索引維護可能會增加對基礎表或索引視圖執行修改、插入、更新或刪除操作所需的時間。
您應該確定修改數據時在查詢性能上的提升是否超過了對性能的影響,以及是否需要額外的磁盤空間要求。有關評估查詢性能的詳細信息,請參閱查詢優化。
說明:“這是因為列值被復制到了索引葉級別”這句很好的說明了物理上的存儲結構和原理。
【圖片解析】
上圖也說明了為什麽不能在聚集索引中建立具有包含性列的索引,因為非聚集索引的葉層是由索引頁而不是由數據頁組成,這就得說到聚集和非聚集索引的的物理存儲了,聚集索引的順序排序和存儲就是基表的順序和存儲結構。
【一個例子】
SELECT UserName,Password,RealName,Mobile,Age FROM bw_Users WHERE UserName = XXX AND Age = XX
說明:
- 這是一個我們很常見的查詢語句,我們如何提高查詢效率呢?
- 首先我們來看看謂詞,這條語句是通過UserName = XXX AND Age = XX作為條件的,那麽我們就應該建立一個組合索引,也稱為復合索引,註意索引中的鍵列的位置,先UserName後Age;
- 其實上面那個是一個非聚集索引,那我們就可以把Password,RealName,Mobile這三列作為索引包含列;
- 所以,最終就是建立一個以UserName 和 Age做為鍵列、Password,RealName,Mobile作為非鍵列的非聚集索引;
- 通常來說我們系統的用戶表並不是很大,所以這樣的優化起不了很明顯的效果,如果有興趣的可以使用大表進行性能測試;
SQL Server 表分區實戰系列(文章索引)
一.本文所涉及的內容(Contents)
- 本文所涉及的內容(Contents)
- 前言(Introduction)
- 實戰說明(In Action)
- 表分區邏輯結構圖(Construction)
- 表分區學習流程圖(Study Step)
- 系列文章索引(Catalog)
- 總結&待續...(Summary & To Be Continued…)
二.前言(Introduction)
前段時間在忙數據庫的表分區,經常會去上網找資料,但是在找到都是測試表分區的文章,沒有實戰經驗的,所以在我把表分區運用到實際項目中的時候遇到了很多問題。
比如:如何確認分區字段?分區字段與聚集索引的區別與聯系?如何存儲分區索引?MSDN說交換分區是以秒計算,但執行40G交換分區超時?如何解決分區不斷增長的問題?自動化交換分區的陷阱?
這些問題都只能自己在實戰中摸索答案,後來我寫了幾篇關於這些問題的博文,希望對那些需要實戰幫助的童鞋有一點提示和幫助。希望大家拍磚。
三.實戰說明(In Action)
某生產數據庫大小已經有800G了,每天進庫數據量大概有150W條記錄(數據空間大概為7G),而服務器現在已經沒有太多的磁盤空間了,面對這樣的問題,我決定對這個數據庫的一個大表做表分區,每個分區的ndf文件為40G,一個分區存儲1千萬條記錄。總的記錄數保持在1.2億的數據量。
當需要新的空間來存儲新的數據的時候,我們就通過交換表分區來快速刪除一個分區的數據,並使用這個分區來存放新進庫的數據。
如果每次都人工來執行交換分區的話就太麻煩了,所以我對這個如何進行交換分區刪除數據來清理磁盤空間做成自動化。
在執行自動化的作業卻也發現了很多問題,在分區文件達到40G的情況,執行交換分區的時間會很長(在正常進數據的情況下執行作業),而對8G的數據文件進行交換分區時速度非常快, 只能先禁用掉MSSQLSERVER網絡協議中的TCP/IP的協議;重啟SQLServer服務;執行Job進行交換分區;
四.表分區邏輯結構圖(Construction)
五.表分區學習流程圖(Study Step)
六.系列文章索引(Catalog)
Step1:SQL Server 合並(刪除)分區解惑
Step2:SQL Server 2005 分區模板與實例
Step3:SQL Server 動態生成分區腳本
Step4:SQL Server 2005 自動化刪除表分區設計方案
Step5:SQL Server 表分區註意事項
Step6:SQL Server 自動化管理分區設計方案(圖解)
Step7:SQL Server 維護計劃備份主分區
Step8:SQL Server 當表分區遇上唯一約束
Step10:SQL Server 解讀【已分區索引的特殊指導原則】(1)- 索引對齊
Step11:SQL Server 解讀【已分區索引的特殊指導原則】(2)- 唯一索引分區
Step12:SQL Server 解讀【已分區索引的特殊指導原則】(3) - 非聚集索引分區
七.總結&待續...(Summary & To Be Continued…)
我會繼續了解和深入表分區的一些知識,並繼續寫一些關於表分區實際應用的文章。但是一個人的能力和視野是比較有限,所以大家如果有更好的分區實戰經驗的話,歡迎拿出來分享和交流。看到一些好的博文也歡迎把地址貼出來。
SQL Server 性能優化實戰系列(二)