¿Cómo puedo obtener el tamaño de datos real por fila en una tabla de SQL Server?


33

Encontré este script sql-server-2005-alcance-tabla-fila-tamaño-límite- que parece devolver el tamaño de la fila por longitudes de tipo de datos definidos. Necesito un script que me dé todas las filas en una tabla en las que su tamaño máximo de datos sea superior al 8024 recomendado (lo que MS recomiende)


2
Puede intentar usar 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')y buscar cualquier cosa donde alloc_unit_type_descestéROW_OVERFLOW_DATA

El servidor MS SQL solo permite almacenar 8060 bytes de datos como máximo en una fila. Por lo tanto, el tamaño de la fila siempre será <= 8060. Nunca cruzará esto.
AnandPhadke

2
@AnandPhadke Esto no es totalmente correcto: msdn.microsoft.com/en-us/library/ms186981%28SQL.90%29.aspx
Jaime

Respuestas:


44

Prueba este 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)

Las filas se ordenarán por tamaño, por lo que puede verificar de arriba a abajo.


sí no es aplicable para varchar I agree.Here por encima de su consulta no está cubriendo todas las columnas de una tabla
AnandPhadke

@AnandPhadke ¿Qué columnas no cubren? Gracias
Jaime

¿Por qué agregar un byte para una columna nula? ¿No es eso cero bytes? ¿O se almacena internamente como # 0?
Paul

2
@Paul, es cero bytes para columnas de longitud variable (varchar, nvarchar ...), pero es la longitud del tipo de datos real para columnas de longitud fija (int, smallint ...), por lo que 1 es una especie de estimación. Los NULL son un Universo entero :) (también hay una máscara de mapa de bits NULL que se usa para marcar los valores NULL, que ocupa algo de espacio). stackoverflow.com/questions/4546273/…
Jaime

@Paul se almacenará como cero bytes si SQL Server está utilizando cualquier compresión de datos.
d.popov

7

Me gustó lo anterior de Jaime. Agregué algunos corchetes para manejar nombres de columnas extraños.

    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

Y me gustó lo anterior de Speedcat y lo extendí para enumerar todas las tablas con recuentos de filas y bytes totales.

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

prueba esto:

;WITH CTE as(select *,LEN(ISNULL(col1,''))+LEN(ISNULL(col2,'')) as row_len from yourtable)
select * from CTE where row_len > 8060
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.