Questions tagged «database-internals»

有关数据库引擎内部工作的技术问题。

1
删除与截断
我试图对DELETE和TRUNCATE命令之间的差异有更深入的了解。我对内部结构的理解大致如下: DELETE->数据库引擎从相关数据页和输入该行的所有索引页中查找并删除该行。因此,索引越多,删除时间越长。 TRUNCATE ->会简单地整体删除表的所有数据页,这使它成为删除表内容的更有效的选择。 假设以上正确(如果不正确,请纠正我): 不同的恢复模式如何影响每个语句?如果有任何作用 删除时,是扫描所有索引还是仅扫描行所在的索引?我假设所有索引都已扫描(而不查找?) 如何复制命令?SQL命令是否在每个订阅服务器上发送和处理?还是MSSQL比这更聪明?

4
表格定义中的列顺序重要吗?
定义表时,按目的对逻辑组中的列和组本身进行排序很有帮助。表中列的逻辑顺序将含义传达给开发人员,并且是一个良好样式的元素。 很清楚 但是,尚不清楚的是,表中列的逻辑顺序是否会对存储层的物理顺序有任何影响,或者是否有其他可能影响的影响。 除了对样式的影响之外,列顺序是否重要? 关于堆栈溢出有一个与此有关的问题,但是它缺乏权威性的答案。

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) …

1
为什么扫描比寻找该谓词要快?
我能够重现我将其描述为意外的查询性能问题。我正在寻找针对内部的答案。 在我的机器上,以下查询执行聚集索引扫描,并花费大约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, …

1
统计信息物理存储在SQL Server中的什么位置?
查询优化器所使用的统计信息在哪里物理存储在SQL Server数据库文件和缓冲池中? 更具体地说,是否有一种方法可以找出使用DMV和/或DBCC的统计信息所使用的页面? 我同时拥有《 SQL Server 2008内部原理》和《 SQL Server内部原理与故障排除》一书,但都没有谈论统计的物理结构。如果没有,我将无法找到此信息。

1
访问相同的LOB数据时逻辑读取不同
这是三个读取相同数据,但报告逻辑读取非常不同的简单测试: 设定 下面的脚本创建一个包含100个相同行的测试表,每个表包含一个xml列,其中包含足够的数据以确保其存储在行外。在我的测试数据库中,每行生成的xml的长度为20204字节。 -- 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) …

2
将列从NOT NULL更改为NULL-到底发生了什么?
我们有一个包含2.3B行的表。我们想将列从NOT NULL更改为NULL。该列包含在一个索引中(而不是聚集索引或PK索引)。数据类型没有改变(它是一个INT)。只是可空性。声明如下: Alter Table dbo.Workflow Alter Column LineId Int NULL 在停止该操作之前,该操作花费了超过10(我们甚至还没有让它运行完毕,因为这是一项阻塞操作,并且花费了太长时间)。我们可能会将表复制到开发服务器,以测试实际需要多长时间。但是,我很好奇,是否有人知道从NOT NULL转换为NULL时SQL Server在做什么?另外,是否需要重建受影响的索引?生成的查询计划不会指示正在发生的事情。 有问题的表是群集的(不是堆)。

1
哈希键探针和残差
说,我们有这样的查询: select a.*,b.* from a join b on a.col1=b.col1 and len(a.col1)=10 假设以上查询使用哈希联接并具有残差,则探测键为col1,残差为len(a.col1)=10。 但是,通过另一个示例,我可以看到探针和残差在同一列。以下是我要说的话的详细说明: 查询: select * from T1 join T2 on T1.a = T2.a 执行计划,突出显示探针和残差: 测试数据: 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 …

4
标识列上的索引是否应该非聚集?
对于具有标识列的表,是否应为标识列创建聚集或非聚集的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 …

2
列大小增加后,为什么创建索引需要花费更长的时间?
我们的供应商更改了整个数据库中几乎所有列的列宽。该数据库约为7TB,可容纳9000多个表。我们正在尝试在具有55亿行的表上创建索引。在供应商升级之前,我们可以在2小时内创建索引。现在需要几天。他们所做的是将任何varchar(xx)的大小增加到varchar(256)。因此,大多数列以前是varchar(18)或varchar(75)等。 无论如何,主键由6列组成,其总宽度为126个字符。现在,升级后,主键为1283个字符,这违反了SQL Server 900个字符的限制。整个表格的列宽从合并的varchar总数为1049到合并的varchar总数为4009。 数据没有增加,表没有比所有列宽增加之前占用更多的“空间”,但是创建像索引这样简单的内容的性能现在花费了不合理的时间。 谁能解释为什么当唯一要做的就是增加列的大小时,创建和索引需要花费那么多的时间吗? 我们尝试创建的索引是非聚集的,因为pk是聚集索引。经过几次尝试创建索引后,我们放弃了。我认为它运行了4到5天没有完成。 我在非生产环境中尝试了此操作,方法是拍摄文件系统快照,并将数据库安装在安静的服务器上。

2
活页和非活页有什么区别?
我一直在运行一些索引使用情况报告,并且正在尝试获取Leaf和Non-leaf的定义。似乎同时存在叶子和非叶子插入,更新,删除,页面合并和页面分配。我真的不知道这意味着什么,或者一个比另一个更好。 如果有人可以给每个简单的定义,并解释为什么叶子或非叶子很重要,不胜感激!

1
集群列存储上的非集群索引存储
在SQL Server中,行存储表上的非唯一非聚集索引在非聚集索引结构的所有级别上都包含基础对象的书签(RID或群集键)。书签作为所有索引级别上非聚集索引键的一部分存储。 另一方面,如果非聚集索引是唯一的,则书签仅在索引的叶级别存在-不作为键的一部分(实际上,书签作为一个或多个包含的列存在)。 在SQL Server 2016中,可以在面向列的表(具有群集列存储索引的表)上构建非群集b树索引。 集群列存储表上非集群b树索引使用的“书签”是什么? 上述唯一索引和非唯一非聚集索引之间的区别是否仍然适用?

4
PostgreSQL 9.6列删除和带有CTE的SQL函数的副作用
如果我有一个包含3列的表(例如A,B和D),并且我不得不引入一个新表(例如C)来替换D的当前位置。我将使用以下方法: 引入2个新列作为C和D2。 将D的内容复制到D2。 删除D。 将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,执行a VACUUM FULL,最后按照此处和此处的建议删除并重新创建该函数,但是这些解决方案均无效(除了它们尝试解决系统表已更改的情况外)。 由于可以使用非常小的数据库,因此我将其导出,删除并重新导入,从而解决了我的功能问题。 我知道这样一个事实,即不应该通过修改系统表来弄乱列的自然顺序(用弄脏手pg_attribute等),如下所示: 是否可以更改Postgres中列的自然顺序? 从我的函数抛出的错误来看,我现在意识到用我的方法移动列的顺序也是不行的。谁能为我的工作为什么也出错提供一些启发? Postgres版本是9.6.0。 这是函数: CREATE OR REPLACE FUNCTION "public"."__post_users" ("facebookid" text, "useremail" text, "username" …

1
varchar(n)的开销是多少?
我想从Postgres文档中询问有关varchar(n)类型的片段的含义: 短字符串(最多126个字节)的存储要求是1个字节加上实际的字符串,其中包括在字符情况下的空格填充。较长的字符串的开销为4个字节,而不是1个字节。 假设我有一个varchar(255)字段。现在,以下语句: 如果此字段包含10个字节的字符串,则开销为1个字节。因此该字符串将使用11个字节。 如果该字段使用140个字节保存字符串,则开销为4个字节。因此该字符串将使用144个字节。 以上这些陈述是正确的吗?这里有人理解文档相同的方式,我不过这里有人指出的开销总是4个字节在这里?

1
直方图以外的基数估计
设定 我在了解基数估算值时遇到了一些麻烦。这是我的测试设置: 2010版本的Stack Overflow数据库 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 dbo.Posts表上没有非聚集索引或统计信息(上有聚集索引Id)。 当要求为此的估计计划时,出来的“估计行” dbo.Posts为1,934.99: EXEC #sp_PostsByCommentCount @CommentCount = 51; 当我要求估算的计划时,会自动创建以下统计信息对象: DBCC SHOW_STATISTICS('dbo.Posts', [_WA_Sys_00000006_0519C6AF]); 其中的重点是: …

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.