Marry-go-round
Ok, hoje não vou falar sobre o Query Processor, mas, por falar em Query Processor, logo devem ser publicadas algumas matérias que escrevi para a SQL Magazine falando sobre o Query Processor mais especificamente sobre o Query Optimizer, quando for lançado eu aviso aqui no Blog.
Hoje vou escrever sobre feature bem interessante relacionada ao Database Engine.
O mecanismo conhecido como “Marry-go-round scanning“, é uma feature que existe no SQL Server Enterprise, veja bem, eu disse Enterprise, portanto sem chance de testar em versões inferiores, voltando ao assunto, o conceito é o seguinte, quando uma consulta é enviada para o SQL ele pode detectar que existe um plano de execução(eita e eu disse que não ia falar sobre eles, mas eles me perseguem J) que está fazendo um scan na mesma tabela ou índice da consulta que foi enviada, caso este plano de execução esteja rodando, ele começa a fazer o scan a partir do scan que já estava rodando, depois que o primeiro scan termina, o segundo scan volta ao inicio da tabela e começa a ler novamente os dados que já haviam sido lidos pela consulta que estava rodando. Unf, ficou meio confuso né? Vamos tentar elaborar um cenário, acho que vai ficar mais fácil de entender.
Imagine que exista uma tabela com 1 milhão de registros e o SQL recebe o seguinte select.
SELECT * FROM TabTeste
Quando o SQL começa a executar o plano de execução da consulta acima, imagine que outra consulta é acionada por outra sessão, fazendo o mesmo select
SELECT * FROM TabTeste
O Engine detecta que já existe um plano fazendo um scan na tabela TabTeste, e se une a ele até fazer a leitura total da tabela, quando o primeiro scan termina, o segundo scan volta para a primeira linha da tabela e faz a leitura até chegar na linha onde ele se juntou ao primeiro scan.
Com isso o SQL aproveita todos os recursos que estavam sendo utilizados pelo primeiro scan e compartilha o processamento para as duas consultas, e cada pagina será lida apenas uma vez para cada usuário.
Isso me fez lembrar de uma ocasião onde li o seguinte, se você quer garantir que a ordenação de sua tabela seja por uma determinada coluna, especifique a coluna no ORDER BY.
Você pode se perguntar, – Ora mas no caso do SQL optar por um plano que ira utilizar um determinado índice, ele irá retornar as linhas conforme a ordem do índice, por ex: Faço um select em uma tabela de clientes e o SQL usa o índice da coluna Nome, as linhas serão retornadas por ordem de nome, ou então faço um select em uma tabela que possui um índice cluster por uma coluna ID do tipo Integer, o SQL irá retornar os dados ordenados pela coluna ID já que o índice cluster ordena os dados na tabela. Na teoria isso está certo, mas existem alguns casos em quem isso não será verdade. Vamos analisar alguns deles:
· Pode acontecer do SQL optar por utilizar paralelismo para retornar os dados, quando isso acontecer a ordem do resultado não será exatamente a esperada, ou seja, ordenado pela coluna do índice.
· Outra situação onde o SQL pode não retornar os dados na ordem esperada é quando ele opta por utilizar o mecanismo de “merry-go-round” mencionado acima.
· Caso você utilize os HINTS NOLOCK e TABLOCK o SQL irá retornar os dados na ordem de alocação do índice, ou seja, na ordem em que os arquivos estão escritos em disco, e nem sempre esta ordem é seqüencial. Mesmo no índice cluster os dados podem estar desalinhados fisicamente, na verdade muita gente equivocadamente diz que um índice cluster ordena os dados fisicamente, e isso não é verdade, este comportamento pode comprovar isso.
Se ficar alguma dúvida fique a vontade em perguntar,
That’s all folks
Cheers