在ORACLE中有一个伪列就是rowid,是唯一标识一条记录的id,通过解析可以显示这个记录所在的文件id、页id、行id。
其实,在SQL Server中也有类似的RID。通过未记录文档的值%%physloc%%,可以返回结果行中的物理位置,通过未记载文档的函数sys.fn_PhysLocFormatter,把这个物理值转化为一个更易于理解的id,也就是(文件id:页id:行id)。
也可以通过未记载的函数sys.fn_PhysLocCraker,来进一步解析获取file_id、page_id、slot_id。
需要注意的是,数据库引擎不能理解%%physloc%%值,如果在一个where子句中使用%%physloc%%,那么SQL Server必须要检查每一行,才知道哪些行是在这个%%physloc%%所指定的位置的页面上,所以不能使用%%physloc%%来查找行。
%%physloc%%值是作为SQL Server产品开发小组的一种调试功能,而被引入的,不打算在产品应用程序中使用,也不会被支持。
除了%%physloc%%值外,还有一个值%%lockres%%,该值可以返回任何键的哈希字符串,从而判断哪些特定的键被锁定了。如果表是一个堆,那么在扫描表时查找锁资源,这个锁资源就是实际行的ID(RID).
堆表
1、建表
if OBJECT_ID('test') is not null
drop table test
go
create table test(id int ,v varchar(10))
insert into test
select 1,'a' union all
select 2,'b' union all
select 3,'c' union all
select 4,'d' union all
select 5,'e' union all
select 6,'f'
go
select *,
%%physloc%% 'physloc',
sys.fn_PhysLocFormatter(%%physloc%%) RID
from test
/*
id v physloc RID
1 a 0x7200000001000000 (1:114:0)
2 b 0x7200000001000100 (1:114:1)
3 c 0x7200000001000200 (1:114:2)
4 d 0x7200000001000300 (1:114:3)
5 e 0x7200000001000400 (1:114:4)
6 f 0x7200000001000500 (1:114:5)
*/
3、通过sys.fn_PhysLocCraker进一步获取:file_id、page_id、slot_id
select test.*,
%%physloc%% 'physloc',
sys.fn_PhysLocFormatter(%%physloc%%) RID,
t.file_id,
t.page_id,
t.slot_id
from test
cross apply sys.fn_PhysLocCracker(%%physloc%%)t
/*
id v physloc RID file_id page_id slot_id
1 a 0x7200000001000000 (1:114:0) 1 114 0
2 b 0x7200000001000100 (1:114:1) 1 114 1
3 c 0x7200000001000200 (1:114:2) 1 114 2
4 d 0x7200000001000300 (1:114:3) 1 114 3
5 e 0x7200000001000400 (1:114:4) 1 114 4
6 f 0x7200000001000500 (1:114:5) 1 114 5
*/
4、通过%%lockres%%获取RID
select *,
%%lockres%% RID
from test
/*
id v RID
1 a 1:114:0
2 b 1:114:1
3 c 1:114:2
4 d 1:114:3
5 e 1:114:4
6 f 1:114:5
*/
聚集索引
5、建表
if OBJECT_ID('test') is not null
drop table test
go
create table test(id int primary key,v varchar(10))
insert into test
select 1,'a' union all
select 2,'b' union all
select 3,'c' union all
select 4,'d' union all
select 5,'e' union all
select 6,'f'
go
6、对聚集索引,%%lockres%%会返回聚集索引键的hash值
select *,
%%lockres%% RID
from test
/*
id v RID
1 a (8194443284a0)
2 b (61a06abd401c)
3 c (98ec012aa510)
4 d (a0c936a3c965)
5 e (59855d342c69)
6 f (b9b173bbe8d5)
*/
非聚集索引
7、建立非聚集索引,%%lockres%%会返回非聚集索引键的hash值
create index idx_test_v on test(v)
go
select *,
%%lockres%% RID
from test with(index = idx_test_v)
/*
id v RID
1 a (e68f92b335d5)
2 b (9f022c0d1674)
3 c (ee263775518c)
4 d (87f9c346bb9f)
5 e (f6ddd83efc67)
6 f (8f506680dfc6)
*/