【问题标题】:how to find rowsize in table如何在表格中查找行大小
【发布时间】:2010-09-11 23:58:41
【问题描述】:

我的一个 DB 已接近允许的大小。

为了找出包含最大数据的表,我使用了以下查询:

exec sp_MSforeachtable @command1="print '?' exec sp_spaceused '?'"

它返回了包含最大数据的罪魁祸首表。

下一步,我想根据大小清理行。为此,我想根据大小对行进行排序。

如何使用查询来实现这一点?有什么工具可以做到这一点吗?

【问题讨论】:

    标签: sql-server tsql


    【解决方案1】:

    这将为您提供按大小排列的行列表,只需相应地设置 @table 和 @idcol(如所写,它将针对 Northwind 示例运行)

    declare @table varchar(20)
    declare @idcol varchar(10)
    declare @sql varchar(1000)
    
    set @table = 'Employees'
    set @idcol = 'EmployeeId'
    set @sql = 'select ' + @idcol +' , (0'
    
    select @sql = @sql + ' + isnull(datalength(' + name + '), 1)' 
        from syscolumns where id = object_id(@table)
    set @sql = @sql + ') as rowsize from ' + @table + ' order by rowsize desc'
    
    exec (@sql)
    

    【讨论】:

      【解决方案2】:

      对于所有表大小,一个更简单的方法是使用this site 的存储过程。 您可以将该存储过程的 select 语句更改为:

      SELECT * 
      FROM #TempTable
      Order by dataSize desc
      

      按大小排序。

      你想怎么清理?清理特定表的最大行?不确定我是否理解这个问题。

      编辑(回复评论)

      假设您的事件日志与我的(DNN 事件日志)具有相同的布局:

      SELECT     LEN(CONVERT(nvarchar(MAX), LogProperties)) AS length
      FROM         EventLog
      ORDER BY length DESC
      

      【讨论】:

      • 没错。有问题的表是 EventLog 表。我当然不想删除所有行,而是按大小降序排列的行。
      • 注意这个查询在 sql 2000 中不起作用,最好使用 datalength
      【解决方案3】:

      您还可以使用它来获取索引和键的大小:(编辑:对不起,文本墙,无法使格式正常工作)

      
      WITH table_space_usage
      ( schema_name, table_name, index_name, used, reserved, ind_rows, tbl_rows )
      AS (
      SELECT s.Name
           , o.Name
           , coalesce(i.Name, 'HEAP')
           , p.used_page_count * 8
           , p.reserved_page_count * 8
           , p.row_count
           , case when i.index_id in ( 0, 1 ) then p.row_count else 0 end
      FROM sys.dm_db_partition_stats p
        INNER JOIN sys.objects as o
          ON o.object_id = p.object_id
        INNER JOIN sys.schemas as s
          ON s.schema_id = o.schema_id
        LEFT OUTER JOIN sys.indexes as i
          on i.object_id = p.object_id and i.index_id = p.index_id
       WHERE o.type_desc = 'USER_TABLE'
         and o.is_ms_shipped = 0
      )
       SELECT t.schema_name
           , t.table_name
           , t.index_name
           , sum(t.used) as used_in_kb
           , sum(t.reserved) as reserved_in_kb
           , case grouping(t.index_name) 
          when 0 then sum(t.ind_rows) 
          else sum(t.tbl_rows) end as rows
       FROM table_space_usage as t
       GROUP BY
             t.schema_name
           , t.table_name
           , t.index_name
       WITH ROLLUP
       ORDER BY
            grouping(t.schema_name)
          , t.schema_name
          , grouping(t.table_name)
          , t.table_name
          , grouping(t.index_name)
          , t.index_name
      

      【讨论】:

        【解决方案4】:

        也许这样的事情会起作用

        delete table where id in 
        (
            select top 100 id
            from table
            order by datalength(event_text) + length(varchar_column) desc
        ) 
        

        (因为您正在处理一个事件表,它可能是您正在查看排序的文本列,因此 datalength sql 命令是这里的关键)

        【讨论】:

        • 删除表?是开玩笑吗?
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-07-11
        • 1970-01-01
        相关资源
        最近更新 更多