标签: database-internals

叶页和非叶页有什么区别?

我一直在运行一些索引使用报告,我正在尝试获得LeafNon-leaf的定义。似乎有叶和非叶插入、更新、删除、页面合并和页面分配。我真的不知道这意味着什么,或者一个是否比另一个更好。

如果有人可以给出每个的简单定义,并解释为什么叶子或非叶子很重要,将不胜感激!

index sql-server-2008 sql-server database-internals

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

标识列上的索引应该是非聚集的吗?

对于具有标识列的表,是否应该为标识列创建聚集或非聚集 PK/唯一索引?

原因是将为查询创建其他索引。使用非聚集索引(在堆上)并返回索引未涵盖的列的查询将使用较少的逻辑 I/O (LIO),因为没有额外的聚集索引 b 树查找步骤?

create table T (
  Id int identity(1,1) primary key, -- clustered or non-clustered? (surrogate key, may be used to join another table)
  A .... -- A, B, C have mixed data type of int, date, varchar, float, money, ....
  B ....
  C ....
  ....)

create index ix_A on T (A)
create index ix_..... -- Many indexes can be created for queries

-- Common query is query on A, B, C, ....
select A, …
Run Code Online (Sandbox Code Playgroud)

performance sql-server database-internals index-tuning heap performance-tuning

19
推荐指数
3
解决办法
5821
查看次数

为什么在列大小增加后创建索引需要更长的时间?

我们的供应商更改了整个数据库中几乎每一列的列宽。数据库大约 7TB,9000 多个表。我们正在尝试在具有 55 亿行的表上创建索引。在供应商升级之前,我们可以在 2 小时内创建索引。现在需要几天时间。他们所做的是将任何 varchar(xx) 大小增加到 varchar(256)。所以大多数列曾经是 varchar(18) 或 varchar(75) 等。

无论如何,主键由 6 列组成,组合宽度为 126 个字符。现在升级后,主键是 1283 个字符,这违反了 SQL Server 900 个字符的限制。整个表列宽度从 1049 的总组合 varchar 计数变为 4009 的总组合 varchar 计数。

数据没有增加,表不会占用比所有列宽增加之前更多的“空间”,但是创建像索引这样简单的东西的性能现在花费了不合理的时间。

任何人都可以解释为什么当唯一要做的就是增加列的大小时,为什么创建和索引需要这么长时间?

我们尝试创建的索引是非聚集的,因为 pk 是聚集索引。在多次尝试创建索引后,我们放弃了。我认为它运行了 4 或 5 天而没有完成。

我在非生产环境中尝试了这一点,方法是拍摄文件系统快照并将数据库放在更安静的服务器上。

sql-server database-internals

18
推荐指数
2
解决办法
455
查看次数

SQL Server 2019 企业版和标准版之间的任务调度是否存在差异?

工作原理:SQL Server 2012 数据库引擎任务计划中,Bob Dorr 解释了 SQL Server 2012 中工作调度程序分配的一些更改。他提到一些改进仅在企业版中可用。这些差异在 SQL Server 2019 中是否仍然存在?

如果这很重要,我会问这个问题,因为我发现 SQL Server 2017 标准版实例上可能存在调度程序效率低下的问题,该实例计划未来升级到企业版。如果升级到企业版可以解决问题,我不想尝试对标准版进行调查。

sql-server database-internals sql-server-2019

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

PostgreSQL 9.6 列删除和对带有 CTE 的 SQL 函数的副作用

如果我有一个包含 3 列的表格——比如 A、B 和 D——并且我不得不引入一个新的——比如 C 来替换 D 的当前位置。我将使用以下方法:

  1. 引入 2 个新列作为 C 和 D2。
  2. 将 D 的内容复制到 D2。
  3. 删除 D。
  4. 将 D2 重命名为 D。

新的顺序是 A、B、C 和 D。

我认为这是一种合法的做法,因为(到目前为止)它没有产生任何问题。

但是,今天我遇到了一个问题,当一个函数在同一张表上执行语句时返回以下错误:

table row type and query-specified row type do not match

以及以下细节:

Query provides a value for a dropped column at ordinal position 13

我尝试重新启动 PostgreSQL,VACUUM FULL按照此处此处的建议执行并最终删除并重新创建该函数,但这些解决方案不起作用(除了他们尝试解决系统表已被更改的情况之外)。

有幸使用一个非常小的数据库,我导出了它,删除了它,然后重新导入它并解决了我的功能问题


我意识到这样一个事实,即不应通过修改系统表(弄脏pg_attribute等)弄乱列的自然顺序,如下所示:

是否可以更改 Postgres 中列的自然顺序?

从我的函数抛出的错误来看,我现在意识到用我的方法改变列的顺序也是一个禁忌。任何人都可以说明为什么我所做的也是错误的? …

postgresql metadata database-internals functions postgresql-9.6

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

直方图外的基数估计

设置

我在理解基数估计时遇到了一些麻烦。这是我的测试设置:

  • Stack Overflow 数据库 2010 版
  • SQL Server 2017 CU15+GDR (KB4505225) - 14.0.3192.2
  • 新 CE(兼容级别 140)

我有这个过程:

USE StackOverflow2010;
GO

CREATE OR ALTER PROCEDURE #sp_PostsByCommentCount
    @CommentCount int
AS
BEGIN
    SELECT * 
    FROM dbo.Posts p
    WHERE 
        p.CommentCount = @CommentCount
    OPTION (RECOMPILE); 
END;
GO
Run Code Online (Sandbox Code Playgroud)

dbo.Posts表上没有非聚集索引或统计信息(在 上有聚集索引Id)。

当为此要求估计计划时,“估计行数”dbo.Posts是 1,934.99:

EXEC #sp_PostsByCommentCount @CommentCount = 51;
Run Code Online (Sandbox Code Playgroud)

当我询问估计计划时,自动创建了以下统计对象:

DBCC SHOW_STATISTICS('dbo.Posts', [_WA_Sys_00000006_0519C6AF]);
Run Code Online (Sandbox Code Playgroud)

SSMS 中统计输出的屏幕截图

其中的亮点是:

  • 统计数据的采样率非常低,为 1.81% (67,796 / 3,744,192)
  • 仅使用了 31 个直方图步骤
  • “所有密度”值为0.03030303(采样了 33 个不同的值)
  • RANGE_HI_KEY直方图中的最后一个是 50,其中EQ_ROWS1 …

sql-server statistics database-internals cardinality-estimates sql-server-2017

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

寻找 FILESTREAM 内幕信息

在 Microsoft SQL Server 2012 上激活 FILESTREAM 功能后,SQL Server 将在系统上创建“隐藏”共享。份额定义如下:

Sharename          FILESTREAM_SHARE
Path               \\?\GLOBALROOT\Device\RsFx0320\<localmachine>\FILESTREAM_SHARE
Remark             SQL Server FILESTREAM share
Maximum users      unlimited
Users Caching      Manual caching of documents 
Permissions        NT-AUTHORITY\Authenticated Users, FULL
Run Code Online (Sandbox Code Playgroud)

该名称是您在SQL Server 配置管理器中最初配置 FILESTREAM 时提供的共享名称。但它是为了什么?

迄今为止

我通读了所有可用的 FILESTREAM 文档,从以下位置开始:

sql-server-2008 sql-server database-internals sql-server-2012 filestream

14
推荐指数
1
解决办法
1618
查看次数

为什么临时表比急切线轴更有效地解决万圣节问题?

考虑以下查询,该查询仅在源表中不存在时才插入源表中的行:

INSERT INTO dbo.HALLOWEEN_IS_COMING_EARLY_THIS_YEAR WITH (TABLOCK)
SELECT maybe_new_rows.ID
FROM dbo.A_HEAP_OF_MOSTLY_NEW_ROWS maybe_new_rows
WHERE NOT EXISTS (
    SELECT 1
    FROM dbo.HALLOWEEN_IS_COMING_EARLY_THIS_YEAR halloween
    WHERE maybe_new_rows.ID = halloween.ID
)
OPTION (MAXDOP 1, QUERYTRACEON 7470);
Run Code Online (Sandbox Code Playgroud)

一种可能的计划形状包括合并连接和急切线轴。Eager spool 运算符用于解决万圣节问题

第一个计划

在我的机器上,上面的代码在大约 6900 毫秒内执行。用于创建表格的重现代码包含在问题的底部。如果我对性能不满意,我可能会尝试加载要插入到临时表中的行,而不是依赖于 Eager spool。这是一种可能的实现:

DROP TABLE IF EXISTS #CONSULTANT_RECOMMENDED_TEMP_TABLE;
CREATE TABLE #CONSULTANT_RECOMMENDED_TEMP_TABLE (
    ID BIGINT,
    PRIMARY KEY (ID)
);

INSERT INTO #CONSULTANT_RECOMMENDED_TEMP_TABLE WITH (TABLOCK)
SELECT maybe_new_rows.ID
FROM dbo.A_HEAP_OF_MOSTLY_NEW_ROWS maybe_new_rows
WHERE NOT EXISTS (
    SELECT 1
    FROM dbo.HALLOWEEN_IS_COMING_EARLY_THIS_YEAR halloween
    WHERE maybe_new_rows.ID = halloween.ID
)
OPTION …
Run Code Online (Sandbox Code Playgroud)

sql-server database-internals sql-server-2017

14
推荐指数
2
解决办法
1593
查看次数

索引唯一性开销

我一直在与我办公室的各种开发人员就索引的成本以及唯一性是否有益或成本高昂(可能两者兼而有之)进行持续辩论。问题的关键是我们的竞争资源。

背景

我之前读过一个讨论,该讨论指出Unique索引不需要额外的维护成本,因为Insert操作会隐式检查它适合 B 树的位置,并且如果在非唯一索引中发现重复项,则将唯一符附加到键的末尾,否则直接插入。在这一系列事件中,Unique索引没有额外成本。

我的同事反对这种说法,他说这Unique是在寻找 B 树中的新位置之后作为第二个操作强制执行的,因此比非唯一索引维护成本更高。

最坏的情况是,我见过带有标识列(固有唯一)的表,它是表的集群键,但明确声明为非唯一。最糟糕的另一方面是我对唯一性的痴迷,所有索引都被创建为唯一的,当无法定义与索引的显式唯一关系时,我将表的 PK 附加到索引的末尾以确保唯一性得到保证。

我经常参与开发团队的代码审查,我需要能够为他们提供通用的指导方针。是的,应该评估每个索引,但是当您有五台服务器,每个服务器有数千个表,而一个表上的索引多达 20 个时,您需要能够应用一些简单的规则来确保一定的质量水平。

Insert与维护非唯一索引的成本相比,唯一性在后端是否有额外成本?其次,将表的主键附加到索引的末尾以确保唯一性有什么问题?

示例表定义

create table #test_index
    (
    id int not null identity(1, 1),
    dt datetime not null default(current_timestamp),
    val varchar(100) not null,
    is_deleted bit not null default(0),
    primary key nonclustered(id desc),
    unique clustered(dt desc, id desc)
    );

create index
    [nonunique_nonclustered_example]
on #test_index
    (is_deleted)
include
    (val);

create unique index
    [unique_nonclustered_example]
on #test_index
    (is_deleted, dt desc, id desc)
include …
Run Code Online (Sandbox Code Playgroud)

sql-server database-internals index-tuning unique-constraint

14
推荐指数
2
解决办法
1237
查看次数

恒定扫描应用

这个问题是关于VALUES这里这里开始的构造的优化器行为探索的延续。我想问一下VALUESAPPLY这次。

使用CROSS APPLY别名作为需要在查询的各个部分中引用的表达式是常见的模式。例如:

CREATE TABLE #data (N int);
INSERT INTO #data VALUES (5), (4), (3), (2), (1);

SELECT d.N, c.[Square]
FROM #data d
    CROSS APPLY (VALUES (d.N * d.N)) c([Square])
WHERE c.[Square] BETWEEN 1 AND 10
ORDER BY c.[Square];
Run Code Online (Sandbox Code Playgroud)

我自己总是CROSS APPLY在这种情况下使用,但有时我会遇到包裹在 inline-TVF 和OUTER APPLY-ed 中的此类表达式。因此,出于好奇,我换CROSSOUTER的exampling查询

SELECT d.N, c.[Square]
FROM #data d
    OUTER APPLY (VALUES (d.N * d.N)) c([Square])
WHERE c.[Square] …
Run Code Online (Sandbox Code Playgroud)

sql-server optimization database-internals

14
推荐指数
1
解决办法
362
查看次数