当我在 SQL Server 中使用大对象 (LOB) 数据类型的变量时,整个变量是否始终保存在内存中?即使是2GB大小?
有几个关于SQL Server内部结构的问题。
让我们假设我们在数据库中有一个表。
SGAM 和 GAM 页面在单个 GAM 间隔(~4GB)内跟踪共享和统一范围,并帮助我们在分配页面/范围时找到合适的范围类型(最初前 8 个页面是从混合范围分配的,这些页面的位置是记录器到 IAM 页面,然后从 GAM 范围(统一范围)和此信息存储在下一个链接的 IAM 页面中)。
假设为表分配了页面,并且表大小超过 8 个页面,稍后,行被删除,留下一些可重用的空间。SQL Server 如何知道扩展区有可用空间?
页面有关于可用空间大小的信息,但检查每个页面太耗时。SGAM 和 GAM 页面中的位没有告诉我们除了扩展已分配或有一些空闲页面(整个页面是空闲的,不是部分空闲的)之外的任何内容。
文件头 & SGAM & GAM & IAM 页是文件中的第一页。什么数据结构实际上指向它们?
在 MySQL、MyISAM 和 InnoDB 中,不是索引的列是否与索引一起在磁盘上排序?
我开始写的一个错误想法:
我认为可能不是,因为它们没有被编入索引;如果它们被排序,那将意味着它们是索引。
这是不正确的,因为每个索引列都是按其自己的内容顺序排序的,但我问的是每行(或仅某些列)及其相应索引的排序。
为了解释一下,我说:这对于通过索引更快地选择并排的行范围很有用。例如,如果我想select * where id >1000 and id<2000(可能是 MySQL 语法有错误,我不太了解),那么 id 列本身可以从磁盘中快速读取,因为它的单元格从 1000 到 2000 可能在物理磁盘上保持在一起. 但是id 1000到2000对应的其他列内容可能会写在物理磁盘的不同位置。如果它们也被排序,它们将被更快地读取。我想,也许 MySQL 会自动对物理磁盘上的列进行排序,以实现此类操作的性能。
它们是否在其他类型的数据库(PostgreSQL 等)中排序?
12 月 27 日:我从 2 个答案中看到,在存在聚集索引/主键的情况下,简单行本身不会在物理磁盘上排序(正如我认为的那样),甚至聚集索引也是未排序,如果它是 b 树,我已经阅读了有关 b 树的内容,并看到它的节点,据我所知,位于磁盘上的随机位置。
考虑以下查询:
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
在我的 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) 我需要创建包含大量小数 (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) 即使在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) 这是一个数据库内部问题。我正在使用 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
关于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 ×8
performance ×2
blob ×1
compression ×1
functions ×1
identity ×1
index ×1
memory ×1
mysql ×1
postgresql ×1