在这篇文章中,作者多次运行查询。我注意到逻辑读取在执行过程中略有不同。总共读了几千页,大约有两页的差异。从上下文中我可以清楚地看出,两次之间不会有写入活动。如果计划发生变化,我预计会有比百分之几更大的变化。
问:哪些因素会导致 SQL Server 在没有数据写入的情况下对同一查询报告不同的逻辑读取计数?
在我的应用程序中,有几次我必须显示按某个字段分页和排序的结果。
例如,按姓氏排序的简单用户列表。正因为如此,因为我也有逻辑删除,而且它是一个多租户应用程序,我通常使用这样的集群索引:
CREATE CLUSTERED INDEX [idx] ON [Users]
(
IsDeleted ASC,
[AccountId] ASC,
[LastName] ASC
)
Run Code Online (Sandbox Code Playgroud)
这意味着像分页一样的查询SELECT TOP(20) * FROM Users WHERE IsDeleted = 0 AND AccountId = xxx按姓氏排序。我知道它不能保证被排序,但在实践中它总是如此。
然而,在这里阅读关于聚集索引的Kimberly Tripp博客文章,她说这样做是一个可怕的想法。更糟糕的是因为 IsDeleted (BIT) 字段不允许我设置
但是,如果我将 CLUSTERED INDEX 更改为唯一 ID,则需要开始使用ORDER BY LastName,这在实践中非常慢。
我的表有几百万条记录(最多几千万条),一般使用如下:
IsDeleted = 0, AccountId = xxxx(只有单个帐户的未删除数据批量更新)。题:
这类表的推荐索引(以及如何排序)是什么?
又如对于这些类型的表将是一个调查结果表包含以下几列IsDeleted (BIT), AccountId (FK GUID), UserId (FK GUID), QuestionKey (NVARCHAR), AnswerValue (TEXT),在我的聚集键是可能(IsDeleted, AccountId, …
几天来,我一直在工作中的网络上进行挖掘,试图弄明白 DBMS(SQL Server 2008 R2 和其他)如何如此快速地将一列添加到大表的末尾。
在高层次上,您可以认为:我可以在末尾放置一个指向新列的指针。但是,在页面级别上,数据页面不是填充了单个记录吗?添加一列是否意味着每个已经满的页面都需要拆分?
即使页面未满,也需要大量数据处理才能将该列添加到每条记录的末尾,更新所有插槽数组,然后通过任何现有索引和/或 IAM 和 GAM 页面级联所有指针更改?
我唯一能想到的是,所有新的列数据都被添加到新的页面中,没有记录的其余部分,并且在整个表树结构中添加指针以引用新的列页面。然而,这似乎会破坏空间局部性。如果是这样,即使我们没有特别请求,DBMS 是否会在幕后处理数据REBUILD?
我正在谈论带有页面的 DBMS 内存管理的位级别,并询问 DBMS 如何能够如此快速地将一列(允许或不允许 NULL 值)添加到一组现有记录中,即使这些记录已经作为一组存在数据页中的位。
我正在学习DBMS的数据格式,发现我们有一个术语:page。
页面是从外部存储(例如磁盘,SSD)获取的主内存中的数据,当这些页面被查询获取时,几个页面将首先“缓存”到低级缓存。
这让我想起了操作系统和计算机体系结构中使用的同一个术语页面。来自 Wiki 的关于这个“分页”的一些正式描述是:
分页是一种内存管理方案,计算机通过该方案从辅助存储器中存储和检索数据以在主存储器中使用。在此方案中,操作系统从称为页的相同大小的块中检索辅助存储中的数据。分页是现代操作系统中虚拟内存实现的重要组成部分,使用二级存储让程序超过可用物理内存的大小。
那么就涉及到第一个问题:
术语页面在 DBMS 和 OS 中具有相同的含义吗?
更进一步:
该问题2是主要的原因,我在这里提高的问题,并开始问自己,为什么NSM,PAX页面专用DBMS。这个问题更笼统,并不关注任何特定的 DBMS。
我想查看特定记录占用了多少 8K 页。
如果您在 AdventureWorks2019 上运行此查询:
SELECT ProductID
,Name
,DATALENGTH(Name) AS SizeInBytes
,LEN(Name) AS NumberOfCharacters
FROM Production.Product
ORDER BY 1
Run Code Online (Sandbox Code Playgroud)
您可以得到每条记录的咬合列表:
| 产品ID | 姓名 | 大小(以字节为单位) | 字符数 |
|---|---|---|---|
| 1 | 可调式竞赛 | 30 | 15 |
| 2 | 轴承球 | 24 | 12 |
| 3 | BB 球轴承 | 30 | 15 |
| 4 | 耳机滚珠轴承 | 42 | 21 |
| 316 | 刀刃 | 10 | 5 |
如何添加包含该记录所用页数的列?
我当然可以,DATALENGTH(Name) / 8 AS PagesTaken但我想知道是否有一些命令可以让我通过SELECT.
当 INSERT 查询被触发时,SQL Server 将其记录在其日志中并向用户发送查询已完成的确认。同时它还更新数据页面。这两者(日志和数据页)都驻留在内存中。
无论恢复模式如何(简单、批量或完整),每当发生检查点时,SQL Server 都会将日志和脏页从内存刷新到磁盘。
问题:假设在向用户发送确认后、检查点之前发生电源故障,那么,由于内存中的日志尚未写入磁盘,即使用户已收到确认,此 INSERT 操作是否会丢失?这是否违反了 ACID 的持久特性?
我刚刚去了一些资源说:
统一范围由单个对象拥有,混合范围最多可以由 8 个对象共享。
但是我无法理解他们的洞察力的含义,比如这种结构的好处是什么?基本上,我是这个领域的新手,所以如果你能提供一些直观的例子和应用程序,将不胜感激。