标签: database-internals

用于并行索引扫描的 STATISTICS IO

假设有一个带有聚集索引的表

create table [a_table] ([key] binary(900) unique clustered);
Run Code Online (Sandbox Code Playgroud)

和一些数据

insert into [a_table] ([key])
select top (1000000) row_number() over (order by @@spid)
from sys.all_columns a cross join sys.all_columns b;
Run Code Online (Sandbox Code Playgroud)

通过检查该表的存储统计

select st.index_level, page_count = sum(st.page_count)
from sys.dm_db_index_physical_stats(
    db_id(), object_id('a_table'), NULL, NULL, 'DETAILED') st
group by rollup (st.index_level)
order by grouping_id(st.index_level), st.index_level desc;
Run Code Online (Sandbox Code Playgroud)

有人能看见

index_level page_count
----------- ----------
8           1
7           7
6           30
5           121
4           487
3           1952
2           7812
1           31249
0           125000
NULL        166659
Run Code Online (Sandbox Code Playgroud)

该表总共需要 166659 页。

然而表扫描 …

sql-server parallelism database-internals sql-server-2014 scan

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

这个索引扫描中这个 Uniq1002 列的目的是什么?

采取以下再现:

USE tempdb;

IF OBJECT_ID(N'dbo.t', N'U') IS NOT NULL
DROP TABLE dbo.t
GO
CREATE TABLE dbo.t
(
    id int NOT NULL 
        PRIMARY KEY 
        NONCLUSTERED 
        IDENTITY(1,1)
    , col1 datetime NOT NULL
    , col2 varchar(800) NOT NULL
    , col3 tinyint NULL
    , col4 sysname NULL
);

INSERT INTO dbo.t (
      col1
    , col2
    , col3
    , col4
    ) 
SELECT TOP(100000) 
      CONVERT(datetime, 
         DATEADD(DAY, CONVERT(int, CRYPT_GEN_RANDOM(1)), '2000-01-01 00:00:00'))
    , replicate('A', 800)
    , sc2.bitpos
    , CONVERT(sysname, CHAR(65 + CRYPT_GEN_RANDOM(1) % 26) 
        + CHAR(65 + CRYPT_GEN_RANDOM(1) …
Run Code Online (Sandbox Code Playgroud)

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

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

“无效的保护选项”

在以下错误消息中,给出的原因是“无效的保护选项”。这说明什么?

SQL Server 检测到基于逻辑一致性的 I/O 错误:保护选项无效

就这个问题而言,我不需要了解有关“如何运行 DBCC”或“检查损坏”的任何信息。我明白了。我只是对“根本原因”部分感到好奇,以及什么可能导致这种基于逻辑一致性的 I/O 错误。

sql-server database-internals

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

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
查看次数

SQL Server 内部内存压力

我正在尝试确定内部内存压力的原因。据我所知,Resource Monitor Ring Buffer 返回一个内部压力指标。例如,通过使用此查询,

SELECT Top (1) *
FROM sys.dm_os_ring_buffers
WHERE ring_buffer_type = 'RING_BUFFER_RESOURCE_MONITOR'
Run Code Online (Sandbox Code Playgroud)

XML 结果(在资源监视器标记内):

<ResourceMonitor>
  <Notification>RESOURCE_MEMPHYSICAL_LOW</Notification>
  <IndicatorsProcess>2</IndicatorsProcess>
  <IndicatorsSystem>0</IndicatorsSystem>
  <NodeId>0</NodeId>
  <Effect type="APPLY_LOWPM" state="EFFECT_OFF" reversed="0">0</Effect>
  <Effect type="APPLY_HIGHPM" state="EFFECT_IGNORE" reversed="0">100789</Effect>
  <Effect type="REVERT_HIGHPM" state="EFFECT_OFF" reversed="0">0</Effect>
</ResourceMonitor>
Run Code Online (Sandbox Code Playgroud)

在Bob Dorr 的这篇文章中,来自 Memory Broker 的收缩信号可能会造成内部内存压力并反映在资源监视器通知中,IndicatorsProcess = 2 (IDX_MEMPHYSICAL_LOW)如上所示。

Slava Oks 的这篇文章展示了另一种使用RING_BUFFER_SINGLE_PAGE_ALLOCATOR. 我对这个特定的环形缓冲区了解不多,因为我从未在我的环境中见过它。

SELECT Top (1) *
FROM sys.dm_os_ring_buffers
WHERE ring_buffer_type = 'RING_BUFFER_SINGLE_PAGE_ALLOCATOR'
Run Code Online (Sandbox Code Playgroud)

这次的 XML 结果:

<Pressure status="0"><AllocatedPages>477</AllocatedPages>
  <AllAllocatedPages>477</AllAllocatedPages>
  <TargetPages>31553</TargetPages>
  <AjustedTargetPages>31553</AjustedTargetPages>
  ...
</Pressure>
Run Code Online (Sandbox Code Playgroud)

我的问题是,哪些内部进程可能会导致内部物理内存压力,从而导致此问题indicator = 2 …

sql-server memory database-internals

6
推荐指数
1
解决办法
1733
查看次数

Berkeley DB 如何管理其文件?

我使用 Berkeley DB (BDB) 作为 JMS 队列的持久存储。当我使用队列中的条目时,底层 BDB 文件不会立即缩小,但最终会缩小。我遇到了 BDB 文件在文件系统上占用大量空间而检索性能下降的问题。

我的条目大小变化很大,但在持久队列中有 400,000 条大约 32kb 的消息并不少见。

我想了解 BDB 如何管理文件,以便我可以限制文件大小/检索性能的条目数。或者我可以排除 BDB 作为我的持久存储机制。

我可能正在搜索错误的术语,但在Oracle 文档The Berkeley DB Book 中没有找到我要查找的内容。如果 BDB 不想让我弄乱它的内部结构,我不会感到惊讶,但如果(至少)没有关于它如何处理其内部结构的概述,我会感到惊讶。

database-internals berkeley-db

6
推荐指数
1
解决办法
1819
查看次数

SQL Server:索引小于 8kb 的表是否有任何性能优势?

如果一个表在 SQL Server 中的大小小于 8kb,那么大概它都存储在一个页面上。因此 - 除了强制执行唯一约束之外 - 是否可以通过应用索引获得任何性能优势?

我的假设是,为了读取这样的表,SQL Server 必须将存储它的单页读取到内存中。因此,从性能的角度来看,<8kb 表上的任何索引都是毫无意义的,因为任何索引都会占用额外的页面,然后您必须读取两页(除非索引包含所需的列)才能获取数据。

因此,除非索引中有一些东西可以以我不理解的方式改进数据处理,或者它有助于查询优化器,否则我的假设是索引这样一个小表是没有意义的。

非常感谢您的专家意见!

(这是一个纯粹的理论问题,以帮助我确保正确理解一些数据库概念......谢谢!)

index sql-server database-internals

6
推荐指数
1
解决办法
587
查看次数

日志文件中单个事务的大小

有没有办法通过查看 SQL Server 2008 中的日志文件从事务日志中找出事务的大小?我的日志文件确实从一些失败的维护作业中意外膨胀,并且似乎不再释放日志空间。所以我想找出语句以及它在特定时间段内在事务日志中使用了多少空间。

我正在考虑使用 fn_dblog(null,null) 的输出并相应地汇总输出。但这似乎相当令人生畏,因为没有官方文档。

欢迎任何建议和帮助。

sql-server sql-server-2008-r2 database-internals transaction-log

6
推荐指数
1
解决办法
118
查看次数

计划“年龄”可以达到零吗?

我正在阅读 Grant Friitchey 的 SQL Server 执行计划,他提到:

SQL Server 不会永远将执行计划保存在内存中。使用“年龄”公式将计划的估计成本乘以计划的使用次数,它们会慢慢地从系统中老化出来。lazywriter 进程是一个内部进程,用于释放所有类型的缓存(包括计划缓存),它会定期扫描缓存中的对象并每次将该值减一。

如果满足以下条件,将从内存中删除该计划:

  • 系统需要更多内存
  • 计划的“年龄”已经到了零
  • 该计划当前未被现有连接引用。

他还在书的前面提到了以下内容:

一旦优化器到达一个执行计划,估计的计划就会被创建并存储在一个称为计划缓存的内存空间中——尽管如果一个计划已经存在于缓存中,这一切都是不同的。

如果实际计划和估计计划不同,我会假设该计划理论上可以达到零。即使它存储在缓存中,这也会使估计的计划执行计数为零。

我的问题是计划年龄可以达到零的不同情况是什么?我的假设是否正确?

弗里奇,G.(2012 年)。SQL Server 执行计划。美国斯普林菲尔德:Simple Talk 出版。

sql-server database-internals plan-cache

6
推荐指数
1
解决办法
718
查看次数

索引页面(页面类型 2)

我试图了解 SQL Server 中的页面拆分,阅读什么是页面拆分发生什么了?为什么会这样?为什么要担心?通过托尼·罗杰森

CREATE TABLE mytest
  (
     something_to_see_in_data CHAR(5) NOT NULL CONSTRAINT pk_mytest PRIMARY KEY CLUSTERED,
     filler                   VARCHAR(3000) NOT NULL
  ) 

go

insert mytest ( something_to_see_in_data, filler ) values( '00001', replicate( 'A', 3000 ) )
insert mytest ( something_to_see_in_data, filler ) values( '00002', replicate( 'B', 1000 ) )
insert mytest ( something_to_see_in_data, filler ) values( '00003', replicate( 'C', 3000 ) )
go
Run Code Online (Sandbox Code Playgroud)

要检查我的表的页面:

DBCC IND ( 0, 'mytest', 1);
Run Code Online (Sandbox Code Playgroud)
CREATE TABLE mytest …
Run Code Online (Sandbox Code Playgroud)

index sql-server database-internals page-splits

6
推荐指数
1
解决办法
941
查看次数