占用SQL Server数据页

时间:2018-03-10 09:26:15

标签: sql-server

这是我创建的测试表。

USE [Test]
GO

SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

CREATE TABLE [dbo].[Table_3]
(
    [id] [int] NOT NULL,
    [itemcode] [int] NOT NULL,
    [value] [decimal](18, 5) NOT NULL,
    [date] [date] NOT NULL,
    [gain] [decimal](18, 5) NULL,
    [loss] [decimal](18, 5) NULL
) ON [PRIMARY]
GO

对于id,对于日期项目可能有三种情况

  1. 获得有限,损失为0.0
  2. 收益为0.0,损失为有限
  3. 获得null和null为null(这意味着我不知道数据)
  4. 根据我的理解,(3.)仍然会在SQL Server的数据页面上保留相当于十进制数据类型的空间以及该列是否为空。对SQL Server 2012,2014和2016的理解是否正确?

    如果是,是否有一种方法(某些数据类型,提示)如果GainLoss为空,则数据库中没有为它们保留空间?

2 个答案:

答案 0 :(得分:1)

你是对的,这些列会占用空间,因为它们是null或有值。

如果您希望这些列中的很大一部分为null并且您需要一种方法来回收该空间,则可以将列定义为SPARSE:

CREATE TABLE [dbo].[Table_3](
    [id] [int] NOT NULL,
    [itemcode] [int] NOT NULL,
    [value] [decimal](18, 5) NOT NULL,
    [date] [date] NOT NULL,
    [gain] [decimal](18, 5) SPARSE NULL,
    [loss] [decimal](18, 5) SPARSE NULL
) ON [PRIMARY]

https://docs.microsoft.com/en-us/sql/relational-databases/tables/use-sparse-columns

答案 1 :(得分:1)

在第二个问题中,DATALENGTH()对您查询中返回的值起作用,而不是列长度:

SELECT pu.post, pu.id_post, pu.name
FROM (SELECT p.*, u.name
      FROM posts p LEFT JOIN
           users u
           ON u.id_user = p.id_user
      WHERE p.id_user = 4 
      ORDER BY p.date DESC 
      LIMIT 10
     ) pu 
ORDER BY pu.date ASC;

您可以看到第一行的DATALENGTH为5,但第二行为9。