Estou experimentando índices clusterizados e não clusterizados no SQL Server e notei algo interessante.
Aqui está uma versão simplificada do meu código 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))
E aqui está o resultado:
+----+--------+-----------------+----------------+--------------------+------------+
| 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) |
+----+--------+-----------------+----------------+--------------------+-----------+
Como você pode ver, o lock e o physloc para os dois conjuntos de resultados são muito diferentes. No passado, sempre acreditei que essas pseudocolunas revelavam informações sobre a dbo.dept
tabela (o índice clusterizado ou o heap), já que estou selecionando a partir dela. Mas estes testes parecem provar que mostram informações sobre como os dados são acessados. Meu entendimento está correto?
%%physloc%%
fornecerá a localização física do item que você pode ver nos resultados como um local de arquivo: página: slot. Esta é a notação comum para identificar um item em uma página de dados (observe que existem outras estruturas que podem não se comportar assim, como árvores de texto e fragmentos). Observe que isso realmente só funciona com itens que usam páginas tradicionais - por exemplo, isso não funcionará em uma tabela Hekaton (sem algum outro índice baseado em página, como columnstore).%%lockres%%
é o hash de bloqueio da linha, como você veria no gerenciador de bloqueios. Isso leva vários itens em consideração para produzir o valor, mas não fornece necessariamente as mesmas informações, pois%%physloc%%
é o hash lógico e não a localização física.Não acredito que nenhum deles mostre como os dados são acessados. Physloc mostra onde os dados estão armazenados fisicamente, lockres realmente não expõe nenhum atributo, pois é uma saída lógica para o conjunto de entradas com hash, uma vez que as funções hash são uma forma de não expor os dados como o physloc faria. Você poderia usá-lo para inferir outros itens sobre as linhas, mas houve casos em que o algoritmo hash demonstrou não ser verdadeiramente único .