天天看點

分享一個SQLSERVER腳本分享一個SQLSERVER腳本

很多時候我們都需要計算資料庫中各個表的資料量很每行記錄所占用空間

這裡共享一個腳本

注意:使用之前要計算哪個資料庫的記錄,請先USE一下要統計表記錄數的那個資料庫!!

工作中遇到的問題

可以說我在實際的工作中 ,在100個問題中有90個都會先用到這個腳本

這裡舉一個我本人工作中遇到的一些問題

問題一:

程式員反映資料庫查詢慢,5分鐘還沒有出結果

我先用這個腳本看一下這個表有多少記錄,大概有1000w+條資料

然後在本地的SSMS裡查詢,确實也是大概4分鐘的樣子才出來資料,看一下執行計劃,發現查詢能使用到索引

看一下資料庫的壓力,并不是很大,我跟會不會跟資料量有關系呢?

程式員要查詢的結果條數是500條資料,業務表是做了分區的,按道理應該不會慢成這樣。。。

後來我再看一下共享出來的那個腳本的結果,發現查詢的結果大小=每行記錄的大小*記錄數

要查詢大概500MB的資料,再傳到用戶端,不慢才怪

為什麽查詢出的結果這麼大?

主要是有幾個大字段:例如:二進制字段和NVARCHAR(MAX)

并且時間範圍跨度比較大

馬上叫程式員改一下查詢的語句,由于是entity framework程式,怎麽改我就不太清楚了,主要是不必要的字段就不查詢處理并且縮小時間範圍

問題二:

還有一些問題也需要知道每行記錄的大小,例如删除表的曆史資料,QA說要保留2013年之前的資料,你需要查出保留的資料或者2013年之前的資料占用多少G空間

再結合目前伺服器的磁盤可用空間,來評估删除的資料是否太多或者太少

那麼流程是:先查出2013年之前的記錄數有多少-》計算表的總記錄數-》計算表的大小-》手工計算每行記錄的大小-》乘以2013年之前的記錄數

如果沒有每行記錄數這個字段,那麼你手工計算,是不是效率就變慢了???

問題三:

導資料的時候,你想知道目前已經導了多少資料了,那麼執行一下這個腳本就可以了,這個腳本基本不會被阻塞

很快就能查出結果

腳本的計算方法

方法一

實際上利用的就是資料行大小的資訊除以記錄數

 方法二

說一下兩種方法的差別

第一種方法是效率高,當表有上億條記錄的時候,如果你使用第二種方法執行AVG(DATALENGTH(C0))是很慢的,因為SQLSERVER要統計字段大小資訊

可能十幾分鐘都出不來結果

當然,第一種方法也有一些缺陷,就是當表的記錄數少的時候,統計出來的每行記錄占用空間是不準确的

因為datainfo這個值是以資料頁大小為機關的,因為就算表隻有一條記錄,那麼也會占用一個資料頁(8KB)

那麼當8KB/1 =8KB,一條記錄肯定不會是8KB大小的,是以記錄少的時候會不準确

但是當記錄數很多的時候,就準确了

分享一個SQLSERVER腳本分享一個SQLSERVER腳本

看一下TB106這個表統計出來的結果值

分享一個SQLSERVER腳本分享一個SQLSERVER腳本
分享一個SQLSERVER腳本分享一個SQLSERVER腳本
分享一個SQLSERVER腳本分享一個SQLSERVER腳本

可以看到是比較準确的

注意:

無論方法一還是方法二都不包括索引所占用的空間 !!

分享一個SQLSERVER腳本分享一個SQLSERVER腳本

總結

大家平時一定會想:究竟DBA有什麼作用?

在這裡就給大家一個例子了,在工作中,程式員是不會關心他要查詢的資料的大小的,他不管三七二十一隻要把資料select出來就行了,然後收工

DBA這裡就要解決資料查詢不出來的問題,一般的程式員覺得查詢500條資料是很少的,根本不會關心表設計,表的字段的資料類型

當工作越來越多,開發任務越來越重的時候更是這樣

是以本人覺得DBA這個角色還是比較重要的o(∩_∩)o 

如有不對的地方,歡迎大家拍磚o(∩_∩)o 

2014-7-7 腳本bug修複

由于算出來每行記錄的精度有問題,我又對腳本的精度進行了改進

分享一個SQLSERVER腳本分享一個SQLSERVER腳本