标签: data-pages

如何将ctid分解为页码和行号?

表中的每一行都有一个系统列 ctid,其类型tid表示该行的物理位置:

create table t(id serial);
insert into t default values;
insert into t default values;
Run Code Online (Sandbox Code Playgroud)
select ctid
     , id
from t;
Run Code Online (Sandbox Code Playgroud)
ctid | ID
:---- | -:
(0,1) | 1
(0,2) | 2

dbfiddle在这里

ctid最合适的类型(例如integerbigintnumeric(1000,0))中获取页码的最佳方法是什么?

我能想到的唯一的办法是非常难看。

postgresql data-pages datatypes cast postgresql-9.4

19
推荐指数
1
解决办法
1万
查看次数

当 SQL Server 没有可用的物理内存时会发生什么?

在谷歌搜索时,我发现了一些相互矛盾的信息。

某些站点指出,当没有为数据留下物理内存时,SQL Server 会将现有数据移动到 TEMPDB(请参阅:SQL Server:揭秘 TempDb 和建议)。

但是其他站点声明,当没有足够的物理内存时,操作系统可以使用 PAGE FILE 并将数据从物理内存移到它(请参阅SQL Server 的页面文件)。

我想知道当 SQL Server 物理内存不足时,它会在哪里写入数据?到 tempdb 还是到 OS Page 文件?或者两者都有?

sql-server data-pages memory tempdb sql-server-2014

16
推荐指数
1
解决办法
2767
查看次数

SQL Server 压缩索引在重建时是否保持压缩状态而不指定数据压缩?

使用页面压缩 ( ALTER INDEX IX1 REBUILD PARTITION = ALL WITH (DATA_COMPRESSION = PAGE))重建其 SQL Server 索引后,后续重建(如某些维护脚本超过某个碎片阈值所做的那样)是否需要再次指定数据压缩?否则索引会被有效地解压吗?

index sql-server data-pages compression

15
推荐指数
1
解决办法
3921
查看次数

SQL Server - 使用聚集索引时如何存储数据页

我最近听说聚集索引中的数据页不是连续存储的。这是真的?

也许数据页通常是连续存储的,但规则有一些例外?或者我听错了,数据页总是连续存储的。

非常感谢。

sql-server data-pages clustered-index

13
推荐指数
1
解决办法
1158
查看次数

槽阵列和总页面大小

我继续在许多论坛和许多博客上看到一个页面的组成如下所示: 页面大小:16 x 512B = 8192B 页眉:= 96B 最大 In_Row 行:= 8060B

这留下 (8192 - 96 - 8060)B = 36B。

好的,这是合乎逻辑且正确的。我的问题是:为什么那么多人说剩下的36B是留给slot array的?

显然,插槽数组在页面上每行给出 2B;所以,它可以小到 2B,大到 1472B:

2B:1 行 * 2B = 2B

1472B:8096B = n*9B(带开销的最小行大小……想想单个 TINYINT 列)+ n*2B(每行槽阵列成本)=> 8096 = 11n => n = 8096 / 11 = 736。

736*2B = 1472B。

由于 14B 版本标签,这使我达到 20。

USE master ;
GO

CREATE DATABASE test ;
GO

USE test ;
GO

ALTER DATABASE test
    SET ALLOW_SNAPSHOT_ISOLATION ON ;
GO

ALTER DATABASE test …
Run Code Online (Sandbox Code Playgroud)

sql-server-2008 storage-engine data-pages database-internals

13
推荐指数
1
解决办法
1538
查看次数

SQL Server 的 8 KB 数据页中未使用 512 字节

我创建了下表:

CREATE TABLE dbo.TestStructure
(
    id INT NOT NULL,
    filler1 CHAR(36) NOT NULL,
    filler2 CHAR(216) NOT NULL
);
Run Code Online (Sandbox Code Playgroud)

然后创建了一个聚集索引:

CREATE CLUSTERED INDEX idx_cl_id 
ON dbo.TestStructure(id);
Run Code Online (Sandbox Code Playgroud)

接下来我用 30 行填充它,每个大小为 256 字节(基于表声明):

DECLARE @i AS int = 0;

WHILE @i < 30
BEGIN
    SET @i = @i + 1;

    INSERT INTO dbo.TestStructure (id, filler1, filler2)
    VALUES (@i, 'a', 'b');
END;
Run Code Online (Sandbox Code Playgroud)

现在根据我在“Training Kit (Exam 70-461): Querying Microsoft SQL Server 2012 (Itzik Ben-Gan)”一书中读到的信息:

SQL Server 在内部以页为单位组织数据文件中的数据。一个页面是一个 8 KB 的单位,属于一个单一的对象;例如,到表或索引。页是读取和写入的最小单位。页面被进一步组织成范围。一个区由八个连续的页面组成。一个范围内的页面可以属于单个对象或多个对象。如果页面属于多个对象,则该范围称为混合范围;如果页面属于单个对象,则该范围称为统一范围。SQL Server 将对象的前八页存储在混合区中。当对象超过八页时,SQL Server 会为此对象分配额外的统一区。通过这种组织,小物体浪费的空间更少,大物体的碎片化程度也更低。

所以这里我有第一个混合范围 …

index sql-server data-pages t-sql

13
推荐指数
2
解决办法
912
查看次数

与 sys.allocation_units 中的表大小不匹配的 DATALENGTH 总和

我的印象是,如果我要对DATALENGTH()表中所有记录的所有字段求和,我将得到表的总大小。我错了吗?

SELECT 
SUM(DATALENGTH(Field1)) + 
SUM(DATALENGTH(Field2)) + 
SUM(DATALENGTH(Field3)) TotalSizeInBytes
FROM SomeTable
WHERE X, Y, and Z are true
Run Code Online (Sandbox Code Playgroud)

我在下面使用了这个查询(我从网上得到的表大小,聚集索引,所以它不包括 NC 索引)来获取我的数据库中特定表的大小。出于计费目的(我们按部门使用的空间量收费),我需要计算出每个部门在此表中使用了多少空间。我有一个查询来标识表中的每个组。我只需要弄清楚每个组占用了多少空间。

由于VARCHAR(MAX)表中的字段,每行的空间可能会剧烈波动,所以我不能只取平均大小 * 部门的行数比率。当我使用上述DATALENGTH()方法时,我只能获得下面查询中使用的总空间的 85%。想法?

SELECT 
s.Name AS SchemaName,
t.NAME AS TableName,
p.rows AS RowCounts,
(SUM(a.total_pages) * 8)/1024 AS TotalSpaceMB, 
(SUM(a.used_pages) * 8)/1024 AS UsedSpaceMB, 
((SUM(a.total_pages) - SUM(a.used_pages)) * 8)/1024 AS UnusedSpaceMB
FROM 
    sys.tables t with (nolock)
INNER JOIN 
    sys.schemas s with (nolock) ON s.schema_id = t.schema_id
INNER JOIN      
    sys.indexes i with (nolock) ON t.OBJECT_ID …
Run Code Online (Sandbox Code Playgroud)

sql-server data-pages clustered-index metadata database-internals

11
推荐指数
2
解决办法
3870
查看次数

删除辅助数据文件。DBCC SHRINKFILE:无法移动页面,因为它是工作表页面

我为 .ndf 创建了太多辅助数据文件 (.ndf) tempdb。要删除多余的文件,我需要清空文件(内容将移动到其他文件):

DBCC SHRINKFILE('tempdbfile8', EMPTYFILE);
Run Code Online (Sandbox Code Playgroud)

然后删除文件:

ALTER DATABASE tempdb REMOVE FILE tempdbfile8;
Run Code Online (Sandbox Code Playgroud)

但是EMPTYFILE命令返回错误:

DBCC SHRINKFILE: Page 8:41920 could not be moved because it is a work table page.
Msg 2555, Level 16, State 1, Line 2
Cannot move all contents of file "tempdbfile8" to other places to complete the emptyfile operation.
Run Code Online (Sandbox Code Playgroud)

不用担心,我只需要找到使用此页面的对象即可:

DBCC TRACEON (3604)
DBCC PAGE(2,8,41920) --dbid=2, fileid=8, pageid=41920
Run Code Online (Sandbox Code Playgroud)

该命令返回了很多信息,其中的object_id。但:

Metadata: ObjectId = 0 
Run Code Online (Sandbox Code Playgroud)

我不知道该怎么办。什么猫阻止了这个页面被移动?如何定位该对象、进程、会话或其他任何内容?任何帮助将不胜感激,但请注意保持原样或删除其他文件不是解决此问题的有效方法;)。

编辑:

我正在删除这些文件,因为我们曾经遵循“最佳实践”,即为每个处理器内核创建一个文件(相同的初始大小,相同的增长率)。但据我所知,在遇到争用问题之前,没有必要在同一设备上创建额外的 tempdb 文件。在我们的例子中,这是有道理的,因为我们打开了MPIO,并且存储设备可以处理 4 个路径。但是有一个错误,我们最终得到了 …

sql-server data-pages dbcc sql-server-2008-r2 datafile

10
推荐指数
1
解决办法
2万
查看次数

使用页面压缩时的行开销是多少?

我创建了一个包含 650 个 Numeric(19,4) 列的表。当我打开页面压缩时,通过运行

ALTER TABLE fct.MyTable REBUILD  WITH (DATA_COMPRESSION = PAGE);
Run Code Online (Sandbox Code Playgroud)

我得到

消息 1975,级别 16,状态 1
索引“PK_Mytable”行长度超过了“8060”字节的最大允许长度。

但是 650 乘以 9 字节仅为 5850 字节,这与规定的 8060 字节的限制相去甚远。

服务器运行的是 Windows 2012 r2 和 SQL Server 2016 SP1 CU2

使用页面压缩时的行开销是多少?

这是一些代码来显示我的意思:

/* test script to demo MSG 1975 */
DECLARE @sql NVARCHAR(max)='', @i INT =0
drop table if exists dbo.mytable;

SET @sql = 'Create table dbo.Mytable (MyTableID bigint not null 
  identity(1,1) primary key clustered, '

WHILE @i < 593 BEGIN
    SET …
Run Code Online (Sandbox Code Playgroud)

data-pages compression sql-server-2016

10
推荐指数
1
解决办法
1448
查看次数

SQL Server:如何创建一个填充 8 KB 页的表?

有没有办法计算填充 SQL Server 中 8 KB 页的数据量并创建一个完全填充一页的表?这篇博文中介绍了这种表格。

sql-server data-pages

6
推荐指数
1
解决办法
1795
查看次数