标签: database-internals

表定义中的列顺序重要吗?

定义表时,按目的对逻辑组中的列和组本身进行排序会很有帮助。表中列的逻辑顺序向开发人员传达了意义,是良好风格的元素。

这是清楚的。

然而,不清楚的是,表中列的逻辑顺序是否对其在存储层的物理顺序有任何影响,或者是否有任何其他人可能关心的影响。

除了对样式的影响之外,列顺序是否重要?

Stack Overflow 上有一个关于这个的问题,但它缺乏权威的答案。

sql-server-2008 database-design sql-server database-internals

38
推荐指数
3
解决办法
2万
查看次数

使用 XML 阅读器优化计划

从这里执行查询以从默认扩展事件会话中提取死锁事件

SELECT CAST (
    REPLACE (
        REPLACE (
            XEventData.XEvent.value ('(data/value)[1]', 'varchar(max)'),
            '<victim-list>', '<deadlock><victim-list>'),
        '<process-list>', '</victim-list><process-list>')
    AS XML) AS DeadlockGraph
FROM (SELECT CAST (target_data AS XML) AS TargetData
    FROM sys.dm_xe_session_targets st
    JOIN sys.dm_xe_sessions s ON s.address = st.event_session_address
    WHERE [name] = 'system_health') AS Data
CROSS APPLY TargetData.nodes ('//RingBufferTarget/event') AS XEventData (XEvent)
    WHERE XEventData.XEvent.value('@name', 'varchar(4000)') = 'xml_deadlock_report';
Run Code Online (Sandbox Code Playgroud)

在我的机器上完成大约需要 20 分钟。报告的统计数据是

Table 'Worktable'. Scan count 0, logical reads 68121, physical reads 0, read-ahead reads 0, 
         lob logical reads 25674576, lob …
Run Code Online (Sandbox Code Playgroud)

xml sql-server execution-plan database-internals sql-server-2012

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

删除与截断

我试图更好地了解DELETETRUNCATE命令之间的差异。我对内部结构的理解大致如下:

DELETE-> 数据库引擎从相关数据页和输入该行的所有索引页中查找并删除该行。因此,索引越多,删除所需的时间就越长。

TRUNCATE -> 简单地删除所有表的数据页,使其成为删除表内容的更有效选项。

假设以上是正确的(如果不正确,请纠正我):

  1. 不同的恢复模式如何影响每个语句?如果有任何影响
  2. 删除时,是扫描所有索引还是仅扫描行所在的索引?我假设所有索引都被扫描(而不是搜索?)
  3. 命令是如何复制的?是否在每个订阅者上发送和处理 SQL 命令?还是 MSSQL 比这更智能一点?

sql-server database-internals

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

为什么扫描比寻找这个谓词要快?

我能够重现一个我认为出乎意料的查询性能问题。我正在寻找一个专注于内部的答案。

在我的机器上,以下查询执行聚集索引扫描并花费大约 6.8 秒的 CPU 时间:

SELECT ID1, ID2
FROM two_col_key_test WITH (FORCESCAN)
WHERE ID1 NOT IN
(
N'1', N'2',N'3', N'4', N'5',
N'6', N'7', N'8', N'9', N'10',
N'11', N'12',N'13', N'14', N'15',
N'16', N'17', N'18', N'19', N'20'
)
AND (ID1 = N'FILLER TEXT' AND ID2 >= N'' OR (ID1 > N'FILLER TEXT'))
ORDER BY ID1, ID2 OFFSET 12000000 ROWS FETCH FIRST 1 ROW ONLY
OPTION (MAXDOP 1);
Run Code Online (Sandbox Code Playgroud)

以下查询执行聚集索引查找(唯一的区别是删除FORCESCAN提示),但需要大约 18.2 秒的 CPU 时间:

SELECT ID1, ID2
FROM two_col_key_test
WHERE ID1 …
Run Code Online (Sandbox Code Playgroud)

performance sql-server database-internals query-performance

30
推荐指数
1
解决办法
2617
查看次数

SQL Server 中的统计信息物理存储在哪里?

查询优化器使用的统计信息物理存储在 SQL Server 数据库文件和缓冲池中的什么位置?

更具体地说,有没有办法使用 DMV 和/或 DBCC 找出统计数据使用的页面?

我拥有 SQL Server 2008 Internals 和 SQL Server Internals and Troubleshooting 书籍,但没有一本涉及统计的物理结构;如果他们这样做,我将无法找到此信息。

sql-server statistics database-internals

28
推荐指数
1
解决办法
4592
查看次数

将一列从 NOT NULL 更改为 NULL - 幕后发生了什么?

我们有一个包含 2.3B 行的表。我们想将一列从 NOT NULL 更改为 NULL。该列包含在一个索引中(不是聚集索引或 PK 索引)。数据类型没有改变(它是一个 INT)。只是可空性。声明如下:

Alter Table dbo.Workflow Alter Column LineId Int NULL
Run Code Online (Sandbox Code Playgroud)

该操作在我们停止之前需要超过 10 次(我们甚至还没有让它运行完成,因为它是一个阻塞操作并且花费的时间太长)。我们可能会将表复制到开发服务器以测试实际需要多长时间。但是,我很好奇是否有人知道 SQL Server 在从 NOT NULL 转换为 NULL 时在幕后做了什么?此外,受影响的索引是否需要重建?生成的查询计划并不表明发生了什么。

有问题的表是集群的(不是堆)。

sql-server sql-server-2008-r2 alter-table database-internals

26
推荐指数
2
解决办法
4万
查看次数

访问相同LOB数据时的逻辑读取不同

以下是三个读取相同数据的简单测试,但报告的逻辑读取却截然不同:

设置

以下脚本创建一个具有 100 个相同行的测试表,每个行都包含一个xml列,其中包含足够的数据以确保将其存储在行外。在我的测试数据库中,生成的xml的长度为每行 20,204 字节。

-- Conditional drop
IF OBJECT_ID(N'dbo.XMLTest', N'U') IS NOT NULL
    DROP TABLE dbo.XMLTest;
GO
-- Create test table
CREATE TABLE dbo.XMLTest
(
    ID integer IDENTITY PRIMARY KEY,
    X xml NULL
);
GO
-- Add 100 wide xml rows
DECLARE @X xml;

SET @X =
(
    SELECT TOP (100) *
    FROM  sys.columns AS C
    FOR XML 
        PATH ('row'),
        ROOT ('root'),
        TYPE
);

INSERT dbo.XMLTest
    (X)
SELECT TOP (100)
    @X
FROM  sys.columns …
Run Code Online (Sandbox Code Playgroud)

performance sql-server database-internals blob

26
推荐指数
1
解决办法
1301
查看次数

哈希键探测和残差

比如说,我们有一个这样的查询:

select a.*,b.*
from 
a join b
on a.col1=b.col1
and len(a.col1)=10
Run Code Online (Sandbox Code Playgroud)

假设上述查询使用 Hash Join 并具有残差,则探测键将为col1,残差将为len(a.col1)=10

但是在查看另一个示例时,我可以看到探针和残差是同一列。以下是对我想说的内容的详细说明:

询问:

select *
from T1 join T2 on T1.a = T2.a 
Run Code Online (Sandbox Code Playgroud)

执行计划,突出显示探测和残差:

在此处输入图片说明

测试数据:

create table T1 (a int, b int, x char(200))
create table T2 (a int, b int, x char(200))

set nocount on
declare @i int
set @i = 0
while @i < 1000
  begin
      insert T1 values (@i * 2, @i * 5, @i)
    set @i = @i …
Run Code Online (Sandbox Code Playgroud)

performance sql-server execution-plan database-internals query-performance

21
推荐指数
1
解决办法
4255
查看次数

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

我一直在运行一些索引使用报告,我正在尝试获得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
查看次数