Sql-Server

計算表的總行大小 - SQL Server

  • May 8, 2020

我在SQL Server中有一個具有以下架構的表“連接” :

[ID] [int] IDENTITY(1,1) NOT NULL,
[User] [nvarchar](20) NOT NULL,
[UserID] [int] NULL,
[True] [bit] NOT NULL,
[Comment] [nvarchar](max) NOT NULL,
[Created] [datetime] NOT NULL,
[Flag] [bit] NULL,
[Destination] [varchar](20) NULL

它在 ID 列上有一個主鍵聚集索引。

我需要每月獲取此表上的條目生成的大小。我已經搜尋了可以幫助我解決此問題的任何現有 SP、函式或任何 DMV,但我只找到瞭如何獲取表的大小而不是每行的大小。此外,我需要每月行的總大小,因此無法獲得整個表上行的總大小/最小值/最大值(如其他 stackexchange 文章中提供的解決方案)。

我的嘗試如下:

USE DB1;
SELECT DATEPART(year,created),
      DATEPART(month,created),
      (count (*))*(4+2*ISNULL((max(len([User]))),2)+4+1+2*ISNULL((max(len([Comment]))),2)+8+1+ISNULL(max(len([Destination])),2)) 'BytesPerMonth'
FROM Connections
GROUP BY DATEPART(year,created),DATEPART(month,created)

在上面,我將行數乘以行的字節大小並考慮以下內容:

int - 4 bytes
nvarchar - 2 bytes per character ([nvarchar](max) also take 2 bytes per character, same as if we had [nvarchar](40), correct?)
bit - 1 byte
datetime - 8 bytes
varchar - 1 byte per character

但是,這僅提供了一個估計值,因為僅考慮了變數列的最大長度和(最大值)乘以行數,這導致比行的實際大小大得多的值。有沒有辦法在這種情況下獲得每行的實際大小?

此外,我知道每行的行標題 - 每行另外 4 個字節(目前我沒有包括這個,因為考慮到變數列的最大值,我的結果已經很大)。此外,我發現由於架構中的變數列,我應該考慮 3 個字節和 8 個字節,是否需要每行/每列考慮它們?如何計算索引的大小?

您可以使用DATALENGTH函式來獲取一行中每一列的字節數。您可以將這些相加得到行的總數,得到 MIN、MAX、AVG 等等。

SELECT DATEPART(year,created) AS [Year],
      DATEPART(month,created) AS [Month],
      COUNT(*) AS Rows,
      SUM(DATALENGTH([User]) + DATALENGTH([UserID]) + DATALENGTH([True]) + DATALENGTH([Comment]) + DATALENGTH([Created]) + DATALENGTH([Flag]) + DATALENGTH([Destination])) AS TotalRowSize,
      AVG(DATALENGTH([User]) + DATALENGTH([UserID]) + DATALENGTH([True]) + DATALENGTH([Comment]) + DATALENGTH([Created]) + DATALENGTH([Flag]) + DATALENGTH([Destination])) AS AvgRowSize,
      MIN(DATALENGTH([User]) + DATALENGTH([UserID]) + DATALENGTH([True]) + DATALENGTH([Comment]) + DATALENGTH([Created]) + DATALENGTH([Flag]) + DATALENGTH([Destination])) AS MinRowSize,
      MAX(DATALENGTH([User]) + DATALENGTH([UserID]) + DATALENGTH([True]) + DATALENGTH([Comment]) + DATALENGTH([Created]) + DATALENGTH([Flag]) + DATALENGTH([Destination])) AS MaxRowSize
FROM Connections
GROUP BY DATEPART(year,created),DATEPART(month,created)

DATALENGTH 的優點是它為可變長度欄位提供了實際使用的字節,因此無需猜測/估計。有關工作範例,請參閱此db<>fiddle 。

引用自:https://dba.stackexchange.com/questions/266697