Wie kann ich die tatsächliche Datengröße pro Zeile in einer SQL Server-Tabelle ermitteln?


33

Ich fand dieses Skript SQL-Server-2005-Erreichen-Tabelle-Zeilengrößenbeschränkung, die die Zeilengröße pro definierten Datentyp Längen zurückzugeben scheint. Ich benötige ein Skript, das mir alle Zeilen in einer Tabelle mit einer maximalen Datengröße über dem empfohlenen Wert von 8024 anzeigt (was auch immer MS empfiehlt).


2
Sie können versuchen, msdn.microsoft.com/en-us/library/ms188917%28v=sql.105%29.aspx zu verwenden - SELECT * FROM sys.dm_db_index_physical_stats(DB_ID(N'Database_Name'), OBJECT_ID(N'Table_Name'), NULL, NULL, 'DETAILED')und nach allem suchen, was aktuellalloc_unit_type_desc istROW_OVERFLOW_DATA

In MS SQL Server können maximal 8060 Byte Daten in einer Zeile gespeichert werden. Ihre Zeilengröße wird daher immer <= 8060 sein. Dies wird niemals überschritten.
AnandPhadke

2
@AnandPhadke Dies ist nicht ganz richtig: msdn.microsoft.com/en-us/library/ms186981%28SQL.90%29.aspx
Jaime

Antworten:


44

Versuchen Sie dieses Skript:

declare @table nvarchar(128)
declare @idcol nvarchar(128)
declare @sql nvarchar(max)

--initialize those two values
set @table = 'YourTable'
set @idcol = 'some id to recognize the row'

set @sql = 'select ' + @idcol +' , (0'

select @sql = @sql + ' + isnull(datalength(' + name + '), 1)' 
        from  sys.columns 
        where object_id = object_id(@table)
        and   is_computed = 0
set @sql = @sql + ') as rowsize from ' + @table + ' order by rowsize desc'

PRINT @sql

exec (@sql)

Die Zeilen werden nach Größe sortiert, sodass Sie von oben nach unten prüfen können.


Ja, es gilt nicht für varchar Ich stimme zu. Hier oben deckt Ihre Abfrage nicht alle Spalten einer Tabelle ab
AnandPhadke

@AnandPhadke Welche Spalten werden nicht behandelt? Vielen Dank
Jaime

Warum ein Byte für eine Nullspalte hinzufügen? Ist das nicht null Bytes? Oder ist es intern als # 0 gespeichert?
Paul

2
@Paul, für Spalten mit variabler Länge sind es null Byte (varchar, nvarchar ...), aber es ist die tatsächliche Datentyplänge für Spalten mit fester Länge (int, smallint ...), also ist 1 eine Art Schätzung. NULLs sind ein ganzes Universum :) (es gibt auch eine NULL-Bitmap-Maske, die verwendet wird, um NULL-Werte zu kennzeichnen, die etwas Platz beanspruchen). stackoverflow.com/questions/4546273/…
Jaime

@Paul wird als null Byte gespeichert, wenn SQL Server eine Datenkomprimierung verwendet.
d.popov

7

Ich mochte die oben von Jaime. Ich habe ein paar eckige Klammern hinzugefügt, um seltsame Spaltennamen zu behandeln.

    declare @table nvarchar(128)
    declare @idcol nvarchar(128)
    declare @sql nvarchar(max)

    --initialize those two values
    set @table = 'YourTable'
    set @idcol = 'some id to recognize the row'

    set @sql = 'select ' + @idcol +' , (0'

    select @sql = @sql + ' + isnull(datalength([' + name + ']), 1)' 
            from sys.columns where object_id = object_id(@table)
    set @sql = @sql + ') as rowsize from ' + @table + ' order by rowsize         desc'

    PRINT @sql

    exec (@sql)

3

Und ich mochte das Obige von Speedcat und erweiterte es, um alle Tabellen mit Zeilenzahlen und Gesamtbytes aufzulisten.

declare @table nvarchar(128)
declare @sql nvarchar(max)
set @sql = ''
DECLARE tableCursor CURSOR FOR  
SELECT name from sys.tables

open tableCursor
fetch next from tableCursor into @table

CREATE TABLE #TempTable( Tablename nvarchar(max), Bytes int, RowCnt int)

WHILE @@FETCH_STATUS = 0  
begin
    set @sql = 'insert into #TempTable (Tablename, Bytes, RowCnt) '
    set @sql = @sql + 'select '''+@table+''' "Table", sum(t.rowsize) "Bytes", count(*) "RowCnt" from (select (0'

    select @sql = @sql + ' + isnull(datalength([' + name + ']), 1) ' 
        from sys.columns where object_id = object_id(@table)
    set @sql = @sql + ') as rowsize from ' + @table + ' ) t '
    exec (@sql)
    FETCH NEXT FROM tableCursor INTO @table  
end

PRINT @sql

CLOSE tableCursor   
DEALLOCATE tableCursor

select * from #TempTable
select sum(bytes) "Sum" from #TempTable

DROP TABLE #TempTable

0

Versuche dies:

;WITH CTE as(select *,LEN(ISNULL(col1,''))+LEN(ISNULL(col2,'')) as row_len from yourtable)
select * from CTE where row_len > 8060
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.