“孤儿记录”在 SQL Server 表中

发布于 2025-01-16 18:30:48 字数 830 浏览 1 评论 0原文

我们在 Azure 中有一个 SQL Server,当我们运行 SELECT count(*) FROM Table 时,我们会得到一定数量的结果 - 例如 10。

通过 SELECT * FROM Table 列出所有记录 我们得到了相同数量的返回行。

在 .NET Core .GetAll() 上运行查询时,我们返回了超过 1000 条记录。手动将一条记录插入到该表的末尾,得到的 Id 超过 3000。

DELETE FROM Table WHERE Id > 10 永远不会完成,即使 WHERE Id > 3000 如果记录 ID 为 3001,则永远不会完成。

使用 SSMS 中索引的属性以及运行 dm_db_index_physical_stats 检查表上的物理统计信息,显示没有幽灵记录,但有超过 1000 个叶级行,这与我们在 .NET 查询中看到的内容相关。

我已经等待这个命令完成 15 分钟了:

ALTER INDEX PK_Table ON Table REBUILD WITH (ONLINE = ON)

那么问题来了:

  1. 为什么现在即使通过 SELECT() 也无法查看这些数据,但它却显示在我们的 .NET 查询以及叶级计数中?
  2. 我们如何称呼这些记录?我将它们称为“幽灵”或“孤立记录”,但 SQL Server 将这个术语用于不同的目的。
  3. 我们如何解决这个问题,我们可以清除损坏/未引用的数据并重建索引,或者获得对数据的访问权限以便我们可以执行手动清除?

我真的很想避免重新创建表并复制数据。

We have a SQL Server in Azure and when we run a SELECT count(*) FROM Table we get a certain number of results - eg 10.

Listing all the records through a SELECT * FROM Table we get the same number of rows returned.

When running a query on .NET Core .GetAll(), we get over 1000 records returned. Inserting a record manually to the end of this table, gives an Id of over 3000.

DELETE FROM Table WHERE Id > 10 never completes, even WHERE Id > 3000 if the Record Id is 3001, never completes.

Checking the physical stats on the table using both the properties of the index within SSMS as well as running dm_db_index_physical_stats shows no ghost records, but over 1000 Leaf Level Rows, which correlates to what we're seeing with our .NET Query.

I've been waiting on this command to complete for 15 minutes:

ALTER INDEX PK_Table ON Table REBUILD WITH (ONLINE = ON)

So questions:

  1. Why is this data now inaccessible to be seen even through a SELECT() but is showing up in our .NET Query as well as the leaf-level count?
  2. What would we call these records? I would call them Ghost or Orphaned records, but SQL Server uses this terminology for different purposes.
  3. How do we resolve this issue that we can either clear the corrupt/unreferenced data and rebuild the index, or gain access to the data so we can perform a manual clearup?

I would really like to avoid having to recreate the table and copy the data across.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

ら栖息 2025-01-23 18:30:52

默认情况下,Azure SQL 数据库使用基于行版本控制的并发模型。如果您的 .NET 应用程序已在未提交的事务中插入行,则它不会阻止其他会话查询该表,但未提交的行将不可见。

您可以使用 NOLOCK 提示读取未提交的行,并使用 DMV 检查其他会话的事务。

我已经等待此命令完成 15 分钟了:

未提交的事务也会阻塞 ALTER INDEX。检查阻塞情况

select * 
from sys.dm_tran_locks

Azure SQL Database uses a row-versioning-based concurrency model by default. If your .NET app has inserted rows in an uncommitted transaction, it would not block other sessions from querying the table, but the uncommitted rows would not be visible.

You can read the uncommitted rows with a NOLOCK hint, and examine the other sessions' transactions and with DMVs.

I've been waiting on this command to complete for 15 minutes:

An uncommitted transaction would also block the ALTER INDEX. Examine the blocking with

select * 
from sys.dm_tran_locks
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文