我正在 SQL Server 中试验聚集索引和非聚集索引,我注意到一些有趣的事情。
这是我的 T-SQL 代码的简化版本:
IF OBJECT_ID('dbo.dept') IS NOT NULL DROP TABLE dbo.dept;
CREATE TABLE dept(id INT, name NVARCHAR(20), address NVARCHAR(50));
GO
INSERT INTO dept(id, name, address) VALUES (1, 'Dept 1', 'Sarjapur Road');
INSERT INTO dept(id, name, address) VALUES (2, 'Dept 2', 'Whitefield');
INSERT INTO dept(id, name, address) VALUES (3, 'Dept 3', 'Electronic City');
INSERT INTO dept(id, name, address) VALUES (4, 'Dept 4', 'Koramangala');
GO
CREATE CLUSTERED INDEX cl ON dbo.dept(id);
CREATE INDEX ncl ON dbo.dept(address);
GO
SELECT *, %%lockres%% lock, %%physloc%% physloc, sys.fn_PhysLocFormatter(%%physloc%%) formatted
FROM dbo.dept WITH (NOLOCK, INDEX (cl))
SELECT *, %%lockres%% lock, %%physloc%% physloc, sys.fn_PhysLocFormatter(%%physloc%%) formatted
FROM dbo.dept WITH (NOLOCK, INDEX (ncl))
这是结果:
+----+--------+-----------------+----------------+--------------------+------------+
| id | name | address | lock | physloc | formatted |
+----+--------+-----------------+----------------+--------------------+------------+
| 1 | Dept 1 | Sarjapur Road | (de42f79bc795) | 0xB01F000004000000 | (4:8112:0) |
| 2 | Dept 2 | Whitefield | (9d6bf8154a2a) | 0xB01F000004000100 | (4:8112:1) |
| 3 | Dept 3 | Electronic City | (052c8c7d9727) | 0xB01F000004000200 | (4:8112:2) |
| 4 | Dept 4 | Koramangala | (1a39e6095155) | 0xB01F000004000300 | (4:8112:3) |
+----+--------+-----------------+----------------+--------------------+------------+
+----+--------+-----------------+----------------+--------------------+-----------+
| id | name | address | lock | physloc | formatted |
+----+--------+-----------------+----------------+--------------------+-----------+
| 3 | Dept 3 | Electronic City | (b64f1cd4ff4f) | 0x1800000003000000 | (3:24:0) |
| 4 | Dept 4 | Koramangala | (4471456166ef) | 0x1800000003000100 | (3:24:1) |
| 1 | Dept 1 | Sarjapur Road | (7948805432b9) | 0x1800000003000200 | (3:24:2) |
| 2 | Dept 2 | Whitefield | (584262fe5906) | 0x1800000003000300 | (3:24:3) |
+----+--------+-----------------+----------------+--------------------+-----------+
正如您所看到的,两个结果集的锁和 physloc 非常不同。过去,我一直相信这些伪列揭示了有关表dbo.dept
(聚集索引或堆)的信息,因为我是从中进行选择的。但这次测试似乎证明它们正在显示有关如何访问数据的信息。我的理解正确吗?
%%physloc%%
将为您提供该项目的物理位置,您可以在结果中看到该位置是文件:页面:插槽位置。这是用于标识数据页上的项目的常用表示法(请注意,还有其他结构可能不具有这种行为,例如文本树和片段)。请注意,这实际上仅适用于使用传统页面的项目 - 例如,这不适用于 Hekaton 表(没有其他基于页面的索引,例如列存储)。%%lockres%%
是行的锁哈希,正如您在锁管理器中看到的那样。这会考虑各种项目来产生值,但它不一定会告诉您相同的信息,因为%%physloc%%
它是逻辑哈希而不是物理位置。我不相信它们会向您展示如何访问数据。Physloc 向您显示数据的物理存储位置,lockres 并不真正公开任何属性,因为它是一组散列输入的逻辑输出,因为散列函数是它们不像 physloc 那样公开数据的一种方式。您可以使用它来推断有关行的其他项目,但在某些情况下,哈希算法已被证明不是真正唯一的。