Come posso ottenere la dimensione effettiva dei dati per riga in una tabella di SQL Server?


33

Ho trovato questo script sql-server-2005-reach-table-row-size-limit che sembra restituire la dimensione della riga per lunghezze di tipo di dati definite. Ho bisogno di uno script che mi dia tutte le righe in una tabella in cui la loro dimensione massima dei dati è oltre l'8024 raccomandato (qualunque cosa MS consiglia)


2
Puoi provare a utilizzare msdn.microsoft.com/en-us/library/ms188917%28v=sql.105%29.aspx - SELECT * FROM sys.dm_db_index_physical_stats(DB_ID(N'Database_Name'), OBJECT_ID(N'Table_Name'), NULL, NULL, 'DETAILED')e cercare qualsiasi cosa alloc_unit_type_descsi troviROW_OVERFLOW_DATA

Il server MS SQL consente di archiviare in una riga solo 8060 byte di dati max. Pertanto, la dimensione della riga sarà sempre <= 8060, senza mai attraversarla.
AnandPhadke,

2
@AnandPhadke Non è del tutto giusto: msdn.microsoft.com/en-us/library/ms186981%28SQL.90%29.aspx
Jaime

Risposte:


44

Prova questo script:

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)

Le righe verranno ordinate per dimensione, in modo da poter controllare dall'alto verso il basso.


sì, non è valido per varchar, sono d'accordo. Qui sopra la tua query non copre tutte le colonne di una tabella
AnandPhadke,

@AnandPhadke Quali colonne non riguardano? Grazie
Jaime,

Perché aggiungere un byte per una colonna nulla? Non è zero byte? O è memorizzato internamente come # 0?
Paul,

2
@Paul, sono zero byte per le colonne a lunghezza variabile (varchar, nvarchar ...), ma è la lunghezza del tipo di dati effettivo per le colonne a lunghezza fissa (int, smallint ...), quindi 1 è una specie di stima. I NULL sono un intero universo :) (esiste anche una maschera bitmap NULL utilizzata per contrassegnare i valori NULL, che occupa un po 'di spazio). stackoverflow.com/questions/4546273/…
Jaime

@Paul verrà archiviato come zero byte se SQL Server utilizza una compressione dei dati.
d.popov,

7

Mi è piaciuto quanto sopra da Jaime. Ho aggiunto alcune parentesi quadre per gestire strani nomi di colonna.

    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

E mi è piaciuto quanto sopra da Speedcat ed estenderlo per elencare tutte le tabelle con conteggi di righe e byte totali.

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

prova questo:

;WITH CTE as(select *,LEN(ISNULL(col1,''))+LEN(ISNULL(col2,'')) as row_len from yourtable)
select * from CTE where row_len > 8060
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.