SQL Passo-a-Passo – Passo 2

Se você acompanhou o primeiro passo, já deve ter criado uma tabela no SQL Server 2008 (tbAlunos) e talvez a tenha até populado.

Para conferir as informações contidas em sua tabela, abra o SQL Management Studio, Selecione "New Query" e digite o comando abaixo:

USE dbTeste
SELECT * FROM tbAlunos
GO

o que significa: retorne todos os campos da tabela tbAlunos
(lembre-se de selecionar as 3 linhas e apertar F5)

Se você preferir aplicar um filtro, use a cláusula WHERE:

USE dbTeste
SELECT * FROM tbAlunos WHERE Aluno = 'Fernanda'
GO

ou para retornar somente alguns campos:

USE dbTeste
SELECT Aluno, Matematica, Ciencias FROM tbAlunos WHERE Aluno = 'Fernanda'
GO

Para quem criou a tabela, mas ainda não a populou, segue uma comando T-SQL que irá fazê-lo:

USE dbTeste
INSERT INTO tbAlunos (Aluno, Matematica, Portugues, Ciencias, Historia, Geografia) VALUES ('Adriana', 9, 10, 9, 10, 9), ('Alexandre', 8, 8, 9, 8, 7), ('Carlos', 10, 8, 8, 7, 8), ('Fernanda', 8, 8, 8, 9, 10), ('Joãozinho', 5, 4, 5, 3, 3)
GO

Mas vamos passar de comandos SQL básicos para um novo conceito: Índices.
O que são índices? Quando usá-los? Como o SQL Server 2008 os implementa?

O que é um Índice?

Um índice ajuda a localizar registros no Banco de Dados de forma mais eficiente, e pode ser utilizado também para garantir que um determinado campo (ou conjunto de campos) contenha(m) valores únicos. Um exemplo é o campo de CPF: o banco não permite o registro de 2 pessoas com o mesmo CPF.

Como localizar registros rapidamente?

A maneira mais básica de localizar um registro é procurando-o, na sequência de registros, até encontrá-lo. É o que chamamos tecnicamente de "table scan", ou seja, varrer a tabela toda...
Este método pode ser eficiente quando o registro buscado for o primeiro da lista. Mas e se for o último?!

Um jeito interessante de resolver este problema é ordenar a tabela pelo campo em questão.

Neste caso, pode ser realizada uma busca por métodos de "bisecção", ou seja, dividir a tabela ao meio e avaliar em que metade o registro se encontra.
Para isso, compara-se o valor do registro na posição equivalente ao "meio" da tabela com o valor buscado. Se for menor, o dado que procuramos está na metade superior. Se for maior, está na metade inferior.

Depois, repetimos o mesmo processo para a metade que sobrou.

Exemplo

Vejamos como funciona na prática: vamos procurar, numa lista de 54 nomes femininos de origem Tupi, o nome PAQUETÁ (que em Tupi quer dizer: Rio cheio de Pacas – verdade!).

A metade na qual o nome se encontra foi copiada à direita da lista anterior, e assim sucessivamente até encontrarmos o nome PAQUETÁ. Repare que foram necessários somente 6 passos, muito menos que os 45 que seriam necessários no caso de “table scan”.

image

Em números…

Este método pode reduzir consideravelmente o tempo de acesso às informações, pois no caso de "table scan", o número médio de "comparações" necessárias é n/2, onde n é o número de linhas da tabela*.

* No melhor caso, o registro buscado está na primeira linha, e é encontrado com 1 único acesso. Mas no pior caso, o registro buscado está na última linha, precisando de n acessos. A média acaba sendo n/2 acessos.

Já com o método da bisecção, o número de acessos necessários é m, onde 2^m >= n.
Ok, ok, sem teorizar demais... No caso de 1000 registros: no passo 1, ficamos com 500 registros. no passo 2, 250 registros. no passo 3, 125 registros. Passo 4: 63 registros. Passo 5: 32 registros. Passo 6: 16 registros. Passo 7: 8 registros: Passo 8: 4 registros. Passo 9: 2 registros. Passo 10: 1 registro - achou!

m no nosso caso é 10

Note que 2^10 (ou 2*2*2*2*2*2*2*2*2*2) = 1024, um número >= o número de registros da tabela (n), c.q.d.

Conclusão: no caso avaliado, a busca sem utilizar um método de "indexação" faria em média 500 "acessos" (o que se traduz diretamente em operações de I/O), e utilizando um método de indexação, o problema é resolvido em no máximo 10 acessos.
BEEEEEM melhor, não?

Próximos Passos

No próximo passo vamos discutir como os índices são implementados no SQL Server 2008, porque o post está ficando grande de novo...