Índices no SQL Server - parte 2

Já explicamos o que são os índices. Foi uma idéia geral. Mostramos, ainda, um plano de execução simples. Fizemos alguns SELECTs que posso agregar nas tabelas a seguir.

# COMANDO
01 SELECT * FROM PESSOA
02 SELECT * FROM PESSOA WHERE COD = 1
03 SELECT NOME FROM PESSOA
04 SELECT NOME FROM PESSOA WHERE NOME = ‘AGNALDO’
05 SELECT COD, NOME FROM PESSOA WHERE NOME = ‘AGNALDO’
06 SELECT * FROM PESSOA WHERE NOME = ‘AGNALDO’
COMANDO SEM ÍNDICE NON-CLUSTERED CLUSTERED e NON-CLUSTERED
01 TABLE SCAN TABLE SCAN CLUSTERED INDEX SCAN
02 TABLE SCAN TABLE SCAN CLUSTERED INDEX SEEK
03 TABLE SCAN INDEX SCAN INDEX SCAN
04 TABLE SCAN INDEX SEEK INDEX SEEK
05 TABLE SCAN TABLE SCAN INDEX SEEK
06 TABLE SCAN TABLE SCAN CLUSTERED INDEX SCAN
COMANDO SEM ÍNDICE NON-CLUSTERED CLUSTERED
e
NON-CLUSTERED
01 TABLE SCAN TABLE SCAN CLUSTERED INDEX SCAN
02 TABLE SCAN TABLE SCAN CLUSTERED INDEX SEEK
03 TABLE SCAN INDEX SCAN INDEX SCAN
04 TABLE SCAN INDEX SEEK INDEX SEEK
05 TABLE SCAN TABLE SCAN INDEX SEEK
06 TABLE SCAN TABLE SCAN CLUSTERED INDEX SCAN

Nesse ponto, temos que sabe o que é a operação:

Devemos atentar para a seguinte observação: SCAN é usado quando a tabela não possui índices que atendam ao select ou quando a quantidade de registros que a query retorna (em percentual) é grande. O SEEK é usado quando existe um índice que é adequado e a quantidade de registros retornados é pequena, percentualmente falando.

As operações executadas nas tabelas/índices foram:

Agora, por que o SQL Server criou planos de execução tão diferentes? Porque ele “sabe” (usando as estatísticas - assunto que abordarei em outro post) qual tipo de acesso tem maior probabilidade de retornar os dados pedidos no menor tempo possível.

E como o SQL Server escreve os índices no disco? Vamos lá.

Para essa explicação, vamos dropar o database que estávamos usando e recriá-lo, junto com a tabela pessoa. Após isso, vamos inserir as 8 pessoas.

Lembro que, para dropar um banco, usamos os comandos:

USE MASTER DROP DATABASE EXEMPLO_INDICE

Após a criação da tabela, fazemos um select na tabela indexes do schema sys (que vou chamar, a partir de agora, de sys.indexes):

SELECT * FROM SYS.INDEXES WHERE OBJECT_ID = OBJECT_ID('PESSOA')

Vemos que existe uma linha na sys.indexes, mesmo PESSOA não tendo índice. Na realidade, sys.indexes armazena dados dos índices (quando existem) e das tabelas. Sabemos que a tabela não possui índice clustered porque seu type_desc é HEAP.

DECLARE @DB_ID INT, @OBJECT_ID INT SELECT @DB_ID = DB_ID(‘EXEMPLO_INDICE’), @OBJECT_ID = OBJECT_ID(‘PESSOA’) DBCC IND(@DB_ID, @OBJECT_ID, -1)

Onde:

Artigos relacionados