标签: database-internals

SQL Server LOB 变量和内存使用情况

当我在 SQL Server 中使用大对象 (LOB) 数据类型的变量时,整个变量是否始终保存在内存中?即使是2GB大小?

sql-server memory database-internals blob

9
推荐指数
1
解决办法
707
查看次数

SQL Server中SGAM&GAM&IAM&PFS的几个问题

有几个关于SQL Server内部结构的问题。

让我们假设我们在数据库中有一个表。

  1. SGAM 和 GAM 页面在单个 GAM 间隔(~4GB)内跟踪共享和统一范围,并帮助我们在分配页面/范围时找到合适的范围类型(​​最初前 8 个页面是从混合范围分配的,这些页面的位置是记录器到 IAM 页面,然后从 GAM 范围(统一范围)和此信息存储在下一个链接的 IAM 页面中)。

    假设为表分配了页面,并且表大小超过 8 个页面,稍后,行被删除,留下一些可重用的空间。SQL Server 如何知道扩展区有可用空间?

    页面有关于可用空间大小的信息,但检查每个页面太耗时。SGAM 和 GAM 页面中的位没有告诉我们除了扩展已分配或有一些空闲页面(整个页面是空闲的,不是部分空闲的)之外的任何内容。

  2. 文件头 & SGAM & GAM & IAM 页是文件中的第一页。什么数据结构实际上指向它们?

sql-server database-internals

8
推荐指数
1
解决办法
2139
查看次数

不是索引的列是否与索引一起在磁盘上排序?

在 MySQL、MyISAM 和 InnoDB 中,不是索引的列是否与索引一起在磁盘上排序?

我开始写的一个错误想法:

我认为可能不是,因为它们没有被编入索引;如果它们被排序,那将意味着它们是索引。

这是不正确的,因为每个索引列都是按其自己的内容顺序排序的,但我问的是每行(或仅某些列)及其相应索引的排序。

为了解释一下,我说:这对于通过索引更快地选择并排的行范围很有用。例如,如果我想select * where id >1000 and id<2000(可能是 MySQL 语法有错误,我不太了解),那么 id 列本身可以从磁盘中快速读取,因为它的单元格从 1000 到 2000 可能在物理磁盘上保持在​​一起. 但是id 1000到2000对应的其他列内容可能会写在物理磁盘的不同位置。如果它们也被排序,它们将被更快地读取。我想,也许 MySQL 会自动对物理磁盘上的列进行排序,以实现此类操作的性能。

它们是否在其他类型的数据库(PostgreSQL 等)中排序?

12 月 27 日:我从 2 个答案中看到,在存在聚集索引/主键的情况下,简单行本身不会在物理磁盘上排序(正如我认为的那样),甚至聚集索引也是未排序,如果它是 b 树,我已经阅读了有关 b 树的内容,并看到它的节点,据我所知,位于磁盘上的随机位置。

mysql index database-internals

8
推荐指数
2
解决办法
971
查看次数

为嵌套循环设置统计 I/O

考虑以下查询:

CREATE PROC dbo.GetPage  @orderid  AS INT    = 0, -- anchor sort key
            @pagesize AS BIGINT = 25
 AS
SELECT
TOP (@pagesize) orderid, orderdate, custid, empid
 FROM dbo.Orders WHERE orderid > @orderid ORDER BY orderid;

exec GetPage 25,25
Run Code Online (Sandbox Code Playgroud)

上述查询的 SET STATISTICS IO 返回:

(25 row(s) affected)
Table 'Orders'. Scan count 1, logical reads 87, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Run Code Online (Sandbox Code Playgroud)

Itzik Ben-Gan 在他的书中对上述内容的解释是这样的:

执行查询计划所涉及的 I/O 成本由以下组成:

  • 查找索引的叶子:3 次读取(索引具有三个级别)。 …

sql-server execution-plan database-internals sql-server-2016

8
推荐指数
1
解决办法
950
查看次数

为什么使用预读(预取)进行更多(和不同数量的)逻辑读取?

在我的 SQL Server 中创建 tpch 数据库后,我尝试了以下查询:

    set statistics io on
    DBCC DROPCLEANBUFFERS;        
    select top 100 * from dbo.lineitem order by l_partkey;
Run Code Online (Sandbox Code Playgroud)

表 lineitem 在 l_partkey 上有一个非聚集索引。我多次发出上述查询,发现每次逻辑读取都不同:

    Table 'lineitem'. Scan count 1, logical reads 1019, physical reads 4, read-ahead reads 1760, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
    Table 'lineitem'. Scan count 1, logical reads 1007, physical reads 4, read-ahead reads 1720, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
    Table 'lineitem'. …
Run Code Online (Sandbox Code Playgroud)

sql-server database-internals

8
推荐指数
1
解决办法
470
查看次数

SQL Server 2014 压缩和最大行大小

我需要创建包含大量小数 (26,8) 列的宽非规范化表(少于 1024 列限制,大多数列将为空或零)。我知道每行限制为 8060 字节,因此我尝试使用页面压缩创建表。下面的代码创建表,插入一行并查询行大小。行大小远低于限制,但如果我尝试向表中再添加一个小数 (26,8) 列,操作将失败并显示错误“创建或更改表 't1' 失败,因为最小行大小为 8074,包括 1256字节的内部开销。”。有没有办法创建具有这么多列的单个表?

drop table t1
GO
create table t1(c1 decimal(26, 8) null)
with (data_compression = page)
GO

declare @i int = 2;
declare @sql varchar(100);
while @i <= 486
begin
    set @sql = 'alter table t1 add c' + convert(varchar, @i) + ' decimal(26, 8) null';
    execute (@sql);
    set @i += 1;
end;
GO


insert into t1(c1) select 0
GO
declare @i int = 2;
declare @sql varchar(100);
while …
Run Code Online (Sandbox Code Playgroud)

sql-server database-internals compression sql-server-2014

8
推荐指数
1
解决办法
1552
查看次数

在 SQL Server 2016 及更高版本上重建中的错误?

问题总结

即使在REBUILD索引之后,碎片聚集索引也表现不佳。如果索引是,REORGANIZED则给定表/索引的性能增加。

我只在 SQL Server 2016 及更高版本上看到这种异常行为,我已经在不同的硬件和不同的版本上测试了这种情况(所有个人机器都具有传统的旋转硬盘)。如果需要更多信息,请告诉我。

这是 SQL Server 2016 及更高版本中的错误吗?


如果有人愿意,我可以提供完整的详细信息和脚本分析,但现在不提供,因为脚本非常大并且会在问题中占用大量空间。

如果您有 SQL Server 2016 及更高版本,请在您的 DEV 环境中测试从下面提供的链接中获取的示例脚本的较短版本。

脚本

-- SECTION 1
/*
Create a Test Folder in the machine and spefiy the drive in which you created
*/
USE MASTER

CREATE DATABASE RebuildTest
ON 
( NAME = 'RebuildTest',
    FILENAME = 'F:\TEST\RebuildTest_db.mdf',
    SIZE = 200MB,
    MAXSIZE = UNLIMITED,
    FILEGROWTH = 50MB )
LOG ON
( NAME = 'RebuildTest_log',
    FILENAME = 'F:\TEST\RebuildTest_db.ldf',
    SIZE = 100MB, …
Run Code Online (Sandbox Code Playgroud)

performance sql-server database-internals

8
推荐指数
1
解决办法
988
查看次数

为什么集合返回函数 (SRF) 在 FROM 子句中运行得更慢?

这是一个数据库内部问题。我正在使用 PostgreSQL 9.5,我想知道为什么设置返回函数 (SRF),也称为表值函数 (TVF) 在FROM子句中运行得更慢,例如当我执行这些命令时,

CREATE TABLE foo AS SELECT * FROM generate_series(1,1e7);
SELECT 10000000
Time: 5573.574 ms
Run Code Online (Sandbox Code Playgroud)

总是比,慢得多

CREATE TABLE foo AS SELECT generate_series(1,1e7);
SELECT 10000000
Time: 4622.567 ms
Run Code Online (Sandbox Code Playgroud)

是否有一个通用规则可以在这里制定,以便我们应该始终FROM子句之外运行 Set-Returning Functions ?

postgresql performance database-internals functions set-returning-functions

8
推荐指数
1
解决办法
483
查看次数

有没有办法查看 SQL Server 2012 如何定义新身份?

关于Microsoft SQL Server 2012 (SP1) - 11.0.3000.0 (X64),有没有办法查看 SQL Server 使用什么机制来计算由创建的表的新标识值SELECT INTO


样本数据

-- Create our base table
CREATE TABLE dbo.A
(A_ID INT IDENTITY(1, 1),
x1 INT,
noise1 int DEFAULT 1,
noise2 char(1) DEFAULT 'S',
noise3 date DEFAULT GETUTCDATE(),
noise4 bit DEFAULT 0);

-- Create random data between the range of [0-3]
INSERT INTO dbo.A(x1)
SELECT s1000.n FROM
( SELECT TOP (10) n = 1 FROM sys.columns) AS s10 -- 10
CROSS JOIN
( SELECT TOP …
Run Code Online (Sandbox Code Playgroud)

sql-server database-internals identity sql-server-2012

7
推荐指数
1
解决办法
629
查看次数

GAM 间隔的步长是多少

出于兴趣,我正在阅读有关Microsoft SQL Server 文件的内部 结构的内容。IAM 页面的连接方式相当明显。然而,我不清楚在哪里可以找到后来的 GAM 页面。

据记载,每个文件中的第一个GAM页是第2页。DBCC PAGE 证实了这一点。上面的链接指出在“4GB”或“64,000 个范围”之后还有另一个 GAM 页面。当我查看这些地方时(它们不是相同的数字),我没有找到 GAM 页面。

在 SQL Server 数据文件中,距离第一个 GAM 页多少页才能找到第二个 GAM 页(GAM 间隔的“跨度”)?

sql-server storage-engine database-internals

7
推荐指数
2
解决办法
748
查看次数