查詢分割資料表的資料存放位置

由於資料量龐大, 為能改善效能, SQL Server 2005 增加了 Partition Table 功能將 table 依 partition function 來做分塊”橫切”的方式存放, 以將常用資料及不常用資料(如歷史訂單資料), 做實體的存放位置劃分, 讓它實際上是同一個表, 但在存放上是在不同的 filegroup 上, 如此一來, 便能有效將資料表做分塊(分區橫切)管理, 若是 partition function 切割有效的話, 對於查詢應用及備份應用應該會有非常大的幫助.

接下來, 我們需要了解的是實作完成後的 partition table 內, 各分區的資料存放筆數狀況, 可以利用兩個系統表來操作取得, 分別為:

  1. sys.partitions : (http://msdn.microsoft.com/zh-tw/library/ms175012.aspx)
  2. sys.dm_db_partition_stats: (http://msdn.microsoft.com/zh-tw/library/ms187737.aspx)

若是要取得某 table 名為 tblTest 這個 table 在各 partition table 中的存放筆數, 可以利用這個查詢:

[SQL]

SELECT ps.partition_number
,ps.row_count, ps.index_id
FROM sys.dm_db_partition_stats ps
INNER JOIN sys.partitions p
ON ps.partition_id = p.partition_id
AND p.[object_id] = OBJECT_ID(‘tblUsers’)

[/SQL]

這樣取得的結果, 一般若非 partition table, 會得到一筆資料, 例如:

d1

其中三個欄位說明如下:

  • partition_number: 指對應的資料分割編號(以1為基礎), 把他想成存放的分區代碼
  • row_count: 這個就是資料筆數
  • index_id: 這個很重要, 0為堆積, 1為clustered, 2以上為non-clustered

若是有無切分 partition table , 但又有多個 index 的 table 會得到如下結果:

d2

其中, 就是 1為clustered, 而9, 11, 12為 non-clustered 的資料.

再來就是看有切 partition table 的結果:

d3

這個案例來自於這篇文章: [SQL Server]如何將現有table調整為partition table (http://bbs.diary.tw/viewtopic.php?f=13&t=464)

其中, 可以清楚地看到 index_id 為0的, 是 partition_number 為1, 2, 3的資料存放筆數狀況, 而 index_id為2的是後來利用增加 primary key non-clustered index 的方式加入的索引, 得到總筆數的一個 index 存放狀況.

簡而言之, 資料存放的方式為 parititon1 放了 2筆, partitiona2放了 3筆, partition3放了4筆資料, 這樣的查詢結果對於要查目前的 partition table內存放資料的對應 parition 狀況應該就有很清楚的結果呈現了.

SQL Server如何新增article到publication

在使用 Replication 時, 若是使用 Transaction 的方式, 若有要新增 article 到 publication 時, 其實很容易.

基本上就只要在原來的 publication 的 property 裡的 articles, 多加上需要 replication 出來的article, 完成後, 他不會自動進行後續, 接下來的動作就是做 snapshot 就行了, 這裡比較討厭的是若是原來的publication資料多, 而加入的 article資料少, 其實很不划算, 不過做完 snapshot 後, replication 機制會開始將該新發行的article schema傳給 subscriber, 讓 subscriber 將沒有的資料寫入, 這樣就完成了.

其實只會做新的部分, 不過因為還是要一個 schema及起始資料, 所以還是得做一個 snapshot 是比較吃資源的地方, 和 alter table的狀況又不太一樣了. 不過操作上還是很直覺也很方便!

參考SQL Server 2005 help 資料: http://msdn.microsoft.com/en-us/library/ms152493(SQL.90).aspx

其中比較重要的是這段:

After adding an article to a publication, you must create a new snapshot for the publication (and all partitions if it is a merge publication with parameterized filters). The Distribution Agent or Merge Agent then copies the schema and data for the new article to the Subscriber (it does not reinitialize the entire publication).

也就是說, 新增完了之後, 要做一次 snapshopt, 不過 agent 會將新的 article 送到 subscriber, 而不會整個 reinitialize!

SQL Server Replication下的異動資料表

若是SQL Server已設定完成Replication的Article時, 進行資料表異動, 其實會透過 DDL 傳送的方式, 將異動的指令也透過複寫的方式送出, 並進行同步. 可以參考相關文章: http://www.replicationanswers.com/AlterSchema2005.asp

不過若是異動的欄位是 Primary Key時, 將會觸發 exception, 發出如下的訊息:

Msg 4929, Level 16, State 1, Line 2
Cannot alter the table ‘tbltest’ because it is being published for replication.

如此一來便無法使用這種 ddl 傳遞的方式將 Replicated Table 的異動送出. 若是要執行這樣的異動需求, 得先解除掉發行及訂閱此 table, 才能進行調整, 調整完成後才能再重新設定回發行及訂閱, 接下來再做 snap shot 進行遞送出去.

SQL Server釋放記憶體方式

若是 SQL Server 2005有突發性的記憶體不足的問題, 可能是一個 bug, 可以參考: http://support.microsoft.com/kb/912439 , 也有可能是記憶體配置的問題, 不過無論如何, 很有可能造成系統的重大負擔而其他服務或 terminal service無法工作, 有個比較快速的解決方式是先清除 server 內的記憶體快取的部分, 可以使用以下幾個指令來處理:

  1. DBCC FREESYSTEMCACHE : 可以參考: http://msdn.microsoft.com/en-us/library/ms178529.aspx
  2. DBCC FREESESSIONCACHE: 可以參考: http://msdn.microsoft.com/en-us/library/ms187781.aspx
  3. DBCC FREEPROCCACHE: 可以參考: http://msdn.microsoft.com/en-us/library/ms174283.aspx

這樣可以快速地爭取到一些 SQL Server釋放出來的記憶體, 並登入 SQL Server 主機進行操作或 reboot, 以降低對系統的傷害.

通常會發生這樣的狀況, 有些是因為記憶配置的問題, 也有 svchost.exe 在網路上使用過量的記憶體等狀況, 但無論如何, 能先爭取登入主機並進行一些急救處理, 以整理或釐清問題所在是相當重要的.

ps. 若要都用預設釋放的指令如下:

DBCC FREESYSTEMCACHE(‘ALL’)
DBCC FREESESSIONCACHE
DBCC FREEPROCCACHE WITH NO_INFOMSGS

可以很快地救急.

SQL Server Transactional Replication注意參數(max text repl size)

在使用 SQL Server Replication 發行資料時, 有個重要的參數必須要特別注意的地方, 就是 max text repl size, (在 SQL 2005也會影響 varchar(MAX) 這種型態的欄位).

參考這篇 最大文字覆寫大小選項 的設定方法來進行調整(利用 sp_configure).

另外在這篇 交易式複寫考量 也有說明在使用 Replication 時, 要注意覆寫資料的 size 上限, 若是在寫入資料大於該設定的 size 時, 將會發生 error, 內容如下:

Length of LOB data (??????) to be replicated exceeds configured maximum 65536

如此一來便會造成寫入失敗而無法成功寫入資料, 這在沒有使用 交易式複寫 時不會發生的問題. 這在使用交易式複寫時要特別注意的地方!

SQL Server Replication預設不會複製nonclustered index

在使用 SQL Server Replication 機制時, 要特別注意有關複寫參數的部分, 由於預設是不會複製 noclustered indexes的, 所以在使用上要特別注意這點. 這樣的預設有好有壞, 好處是複寫出來到訂閱者資料庫的彈性相當大, 可以依需要再進行 index 設計及應用, 壞處是若管理人員或使用人員沒有發現, 在使用上將會有某種影響訂閱者資料庫的效能!

閱讀全文