Versuchen Sie dies ... das bringt mich nahe. Ich habe den msdn-Artikel zum Erstellen verwendet. Sie können die Anzahl der Zeilen festlegen. Dies wird jede Tabelle in der Datenbank einschließlich der Indizes tun. Führt noch keine columnstores aus und behandelt keine Beziehungen. Es wird nur die rowcount-Schätzung auf jede Tabelle angewendet.
/*Do NOT change this section*/
GO
CREATE TABLE RowSizes (TypeName VARCHAR(30), TableName VARCHAR(255), IndexName VARCHAR(255), Null_Bitmap SMALLINT, VariableFieldSize BIGINT, FixedFieldSize BIGINT, Row_Size BIGINT, LOBFieldSize BIGINT);
CREATE TABLE LeafSizes (TypeName VARCHAR(30), TableName VARCHAR(255), IndexName VARCHAR(255), Row_Size BIGINT, Rows_Per_Page BIGINT, Free_Rows_Per_Page BIGINT, Non_Leaf_Levels BIGINT, Num_Leaf_Pages BIGINT, Num_Index_Pages BIGINT, Leaf_space_used_bytes BIGINT);
GO
CREATE PROCEDURE dbo.cp_CalcIndexPages
@IndexType VARCHAR(20)
AS
BEGIN
DECLARE @IndexName VARCHAR(255)
, @TableName varchar(255)
, @Non_Leaf_Levels bigint = 127
, @Rows_Per_Page bigint = 476
, @Num_Leaf_Pages bigint =10000;
WHILE EXISTS(SELECT TOP 1 1 FROM dbo.LeafSizes WHERE TypeName = @IndexType AND Num_Index_Pages = 0)-- AND IndexName = 'PK_ProcessingMessages')
BEGIN
SELECT TOP 1 @IndexName = IndexName
, @TableName = TableName
, @Non_Leaf_Levels = Non_Leaf_Levels
, @Rows_Per_Page = Rows_Per_Page
, @Num_Leaf_Pages = Num_Leaf_Pages
FROM dbo.LeafSizes
WHERE TypeName = @IndexType
AND Num_Index_Pages = 0;
DECLARE @Counter INT = 1
, @Num_Index_Pages INT = 0;
WHILE @Counter <= @Non_Leaf_Levels
BEGIN
BEGIN TRY
SELECT @Num_Index_Pages += ROUND(CASE WHEN @Num_Leaf_Pages/POWER(@Rows_Per_Page, @Counter) < CONVERT(FLOAT, 1) THEN 1 ELSE @Num_Leaf_Pages/POWER(@Rows_Per_Page, @Counter) END, 0)
END TRY
BEGIN CATCH
SET @Num_Index_Pages += 1
END CATCH
SET @Counter += 1
END
IF @Num_Index_Pages = 0
SET @Num_Index_Pages = 1;
UPDATE dbo.LeafSizes
SET Num_Index_Pages = @Num_Index_Pages
, Leaf_space_used_bytes = 8192 * @Num_Index_Pages
WHERE TableName = @TableName
AND IndexName = @IndexName;
END
END
GO
/*Do NOT change above here*/
--Set parameters here
DECLARE @NumRows INT = 1000000 --Number of rows for estimate
,@VarPercentFill money = .6; --Percentage of variable field space used to estimate. 1 will provide estimate as if all variable columns are 100% full.
/*Do not change*/
WITH cte_Tables AS (--Get Tables
SELECT o.object_id, s.name+'.'+o.name AS ObjectName
FROM sys.objects o
INNER JOIN sys.schemas s ON o.schema_id = s.schema_id
WHERE type = 'U'
), cte_TableData AS (--Calculate Field Sizes
SELECT o.ObjectName AS TableName
, SUM(CASE WHEN t.name IN ('int', 'bigint', 'tinyint', 'char', 'datetime', 'smallint', 'date') THEN 1 ELSE 0 END) AS FixedFields
, SUM(CASE WHEN t.name IN ('int', 'bigint', 'tinyint', 'char', 'datetime', 'smallint', 'date') THEN c.max_length ELSE 0 END) AS FixedFieldSize
, SUM(CASE WHEN t.name IN ('varchar') THEN 1 ELSE 0 END) AS VariableFields
, SUM(CASE WHEN t.name IN ('varchar') THEN c.max_length ELSE 0 END)*@VarPercentFill AS VariableFieldSize
, SUM(CASE WHEN t.name IN ('xml') THEN 1 ELSE 0 END) AS LOBFields
, SUM(CASE WHEN t.name IN ('xml') THEN 10000 ELSE 0 END) AS LOBFieldSize
, COUNT(1) AS TotalColumns
FROM sys.columns c
INNER JOIN cte_Tables o ON o.object_id = c.object_id
INNER JOIN sys.types t ON c.system_type_id = t.system_type_id
GROUP BY o.ObjectName
), cte_Indexes AS (--Get Indexes and size
SELECT s.name+'.'+o.name AS TableName
, ISNULL(i.name, '') AS IndexName
, i.type_desc
, i.index_id
, SUM(CASE WHEN t.name IN ('tinyint','smallint', 'int', 'bigint', 'char', 'datetime', 'date') AND c.key_ordinal > 0 THEN 1 ELSE 0 END) AS FixedFields
, SUM(CASE WHEN t.name IN ('tinyint','smallint', 'int', 'bigint', 'char', 'datetime', 'date') AND c.key_ordinal > 0 THEN tc.max_length ELSE 0 END) AS FixedFieldSize
, SUM(CASE WHEN t.name IN ('varchar') AND c.key_ordinal > 0 THEN 1 ELSE 0 END) AS VariableFields
, SUM(CASE WHEN t.name IN ('varchar') AND c.key_ordinal > 0 THEN tc.max_length ELSE 0 END)*@VarPercentFill AS VariableFieldSize
, SUM(CASE WHEN t.name IN ('xml') AND c.key_ordinal > 0 THEN 1 ELSE 0 END) AS LOBFields
, SUM(CASE WHEN t.name IN ('xml') AND c.key_ordinal > 0 THEN 10000 ELSE 0 END) AS LOBFieldSize
, SUM(CASE WHEN t.name IN ('tinyint','smallint', 'int', 'bigint', 'char', 'datetime', 'date') AND c.is_included_column > 0 THEN 1 ELSE 0 END) AS FixedIncludes
, SUM(CASE WHEN t.name IN ('tinyint','smallint', 'int', 'bigint', 'char', 'datetime', 'date') AND c.is_included_column > 0 THEN 1 ELSE 0 END) AS FixedIncludesSize
, SUM(CASE WHEN t.name IN ('varchar') AND c.is_included_column > 0 THEN 1 ELSE 0 END)*@VarPercentFill AS VariableIncludes
, SUM(CASE WHEN t.name IN ('varchar') AND c.is_included_column > 0 THEN tc.max_length ELSE 0 END) AS VariableIncludesSize
, COUNT(1) AS TotalColumns
FROM sys.indexes i
INNER JOIN sys.columns tc ON i.object_id = tc.object_id
INNER JOIN sys.index_columns c ON i.index_id = c.index_id
AND c.column_id = tc.column_id
AND c.object_id = i.object_id
INNER JOIN sys.objects o ON o.object_id = i.object_id AND o.is_ms_shipped = 0
INNER JOIN sys.schemas s ON o.schema_id = s.schema_id
INNER JOIN sys.types t ON tc.system_type_id = t.system_type_id
GROUP BY s.name+'.'+o.name, ISNULL(i.name, ''), i.type_desc, i.index_id
)
INSERT RowSizes
SELECT 'Table' AS TypeName
, n.TableName
, '' AS IndexName
, 2 + ((n.FixedFields+n.VariableFields+7)/8) AS Null_Bitmap
, 2 + (n.VariableFields * 2) + n.VariableFieldSize AS Variable_Data_Size
, n.FixedFieldSize
/*FixedFieldSize + Variable_Data_Size + Null_Bitmap*/
, n.FixedFieldSize + (2 + (n.VariableFields * 2) + (n.VariableFieldSize)) + (2 + ((n.FixedFields+n.VariableFields+7)/8)) + 4 AS Row_Size
, n.LOBFieldSize
FROM cte_TableData n
UNION
SELECT i.type_desc
, i.TableName
, i.IndexName
, 0 AS Null_Bitmap
, CASE WHEN i.VariableFields > 0 THEN 2 + (i.VariableFields * 2) + i.VariableFieldSize + 4 ELSE 0 END AS Variable_Data_Size
, i.FixedFieldSize
/*FixedFieldSize + Variable_Data_Size + Null_Bitmap if not clustered*/
, i.FixedFieldSize + CASE WHEN i.VariableFields > 0 THEN 2 + (i.VariableFields * 2) + i.VariableFieldSize + 4 ELSE 0 END + 7 AS Row_Size
, i.LOBFieldSize
FROM cte_Indexes i
WHERE i.index_id IN(0,1)
UNION
SELECT i.type_desc
, i.TableName
, i.IndexName
, CASE WHEN si.TotalColumns IS NULL THEN 2 + ((i.FixedFields+i.VariableFields+i.VariableIncludes+i.FixedIncludes+8)/8)
ELSE 2 + ((i.FixedFields+i.VariableFields+i.VariableIncludes+i.FixedIncludes+7)/8)
END AS Null_Bitmap
, CASE WHEN si.TotalColumns IS NULL THEN 2 + ((i.VariableFields + 1) * 2) + (i.VariableFieldSize + 8)
ELSE 2 + (i.VariableFields * 2) + i.VariableFieldSize
END AS Variable_Data_Size
, CASE WHEN si.TotalColumns IS NULL THEN si.FixedFieldSize
ELSE i.FixedFieldSize + si.FixedFieldSize
END AS FixedFieldSize
/*FixedFieldSize + Variable_Data_Size + Null_Bitmap if not clustered*/
, CASE WHEN si.TotalColumns IS NULL THEN i.FixedFieldSize + (2 + ((i.VariableFields + 1) * 2) + (i.VariableFieldSize + 8)) + (2 + ((i.TotalColumns+8)/8)) + 7
ELSE i.FixedFieldSize + (2 + (i.VariableFields * 2) + i.VariableFieldSize) + (2 + ((i.TotalColumns+7)/8)) + 4
END AS Row_Size
, i.LOBFieldSize
FROM cte_Indexes i
LEFT OUTER JOIN cte_Indexes si ON i.TableName = si.TableName AND si.type_desc = 'CLUSTERED'
WHERE i.index_id NOT IN(0,1) AND i.type_desc = 'NONCLUSTERED';
--SELECT * FROM RowSizes
/*Calculate leaf sizes for tables and HEAPs*/
INSERT LeafSizes
SELECT r.TypeName
, r.TableName
,'' AS IndexName
, r.Row_Size
, 8096/(r.Row_Size + 2) AS Rows_Per_Page
, 8096 * ((100 - 90)/100)/(r.Row_Size + 2) AS Free_Rows_Per_Page
, 0 AS Non_Leaf_Levels
/*Num_Leaf_Pages = Number of Rows/(Rows_Per_Page - Free_Rows_Per_Page) OR 1 if less than 1*/
, CASE WHEN @NumRows/((8096/(r.Row_Size + 2)) - (8096 * ((100 - 90)/100)/(r.Row_Size + 2))) < 1
THEN 1
ELSE @NumRows/((8096/(r.Row_Size + 2)) - (8096 * ((100 - 90)/100)/(r.Row_Size + 2)))
END AS Num_Leaf_Pages
, 0 AS Num_Index_Pages
/*Leaf_space_used = 8192 * Num_Leaf_Pages*/
, 8192 * CASE WHEN @NumRows/((8096/(r.Row_Size + 2)) - (8096 * ((100 - 90)/100)/(r.Row_Size + 2))) < 1
THEN 1
ELSE @NumRows/((8096/(r.Row_Size + 2)) - (8096 * ((100 - 90)/100)/(r.Row_Size + 2)))
END + (@NumRows * LOBFieldSize) AS Leaf_space_used_bytes
FROM RowSizes r
WHERE r.TypeName = 'Table'
ORDER BY TypeName, TableName;
/*Calculate leaf sizes for CLUSTERED indexes*/
INSERT LeafSizes
SELECT r.TypeName
, r.TableName
, r.IndexName
, r.Row_Size
, 8096/(r.Row_Size + 2) AS Rows_Per_Page
, 0 AS Free_Rows_Per_Page
, 1 + ROUND(LOG(8096/(r.Row_Size + 2)), 0)*(l.Num_Leaf_Pages/(8096/(r.Row_Size + 2))) AS Non_Leaf_Levels
, l.Num_Leaf_Pages
, 0 AS Num_Index_Pages
, 0 AS Leaf_space_used_bytes
FROM RowSizes r
INNER JOIN LeafSizes l ON r.TableName = l.TableName AND l.TypeName = 'Table'
WHERE r.TypeName = 'CLUSTERED';
PRINT 'CLUSTERED'
EXEC dbo.cp_CalcIndexPages @IndexType = 'CLUSTERED'
/*Calculate leaf sizes for NONCLUSTERED indexes*/
INSERT LeafSizes
SELECT r.TypeName
, r.TableName
, r.IndexName
, r.Row_Size
, 8096/(r.Row_Size + 2) AS Rows_Per_Page
, 0 AS Free_Rows_Per_Page
, 1 + ROUND(LOG(8096/(r.Row_Size + 2)), 0)*(l.Num_Leaf_Pages/(8096/(r.Row_Size + 2))) AS Non_Leaf_Levels
, l.Num_Leaf_Pages
, 0 AS Num_Index_Pages
, 0 AS Leaf_space_used_bytes
FROM RowSizes r
INNER JOIN LeafSizes l ON r.TableName = l.TableName AND l.TypeName = 'Table'
WHERE r.TypeName = 'NONCLUSTERED';
PRINT 'NONCLUSTERED'
EXEC dbo.cp_CalcIndexPages @IndexType = 'NONCLUSTERED'
SELECT *
FROM dbo.LeafSizes
--WHERE TableName = 'eligibility.clientrequest'
SELECT TableName
, @NumRows AS RowsPerTable
, @VarPercentFill*100 AS VariableFieldFillFactor
, SUM(CASE WHEN TypeName = 'Table' THEN Leaf_space_used_bytes ELSE 0 END)/1024/1024 AS TableSizeMB
, SUM(Leaf_space_used_bytes)/1024/1024 AS SizeWithIndexesMB
FROM LeafSizes
--WHERE TableName = 'eligibility.clientrequest'
GROUP BY TableName
ORDER BY TableName;
GO
/*Cleanup when done*/
DROP PROCEDURE dbo.cp_CalcIndexPages;
DROP TABLE dbo.RowSizes;
DROP TABLE dbo.LeafSizes;
Ich bin mir nicht sicher, aber eine schnelle Google-Suche bringt eine offizielle MSDN-Seite, die genauere Anweisungen hat ... vielleicht versuchen Sie das? https://msdn.microsoft.com/en-us/library/ms175991.aspx (Sieht aus wie vielleicht berechnet es die Größe des Indexes, der ganz anders als der gesamte Datenfußabdruck ist) – jleach
Ich versuche es tatsächlich. Aber ich habe einige Unterschiede (fast 10MB). – Cedric
Anstatt Durchschnitt, können Sie die Länge von "Wert" summieren. –