2009-12-18

Índices sobre booleanos

Na 4º feira tive um ínicio de noite muito interessante, a tentar optimizar uma migração de dados que teimava em não processar mais de 75 registos por minuto, dos mais de 900.000 que tinha para processar.
A causa era uma query que demorava à volta de 600 milisegundos e que na prática era bastante simples: obter o primeiro registo em que um booleano estivesse a 0 ordenado por um campo de data.
A minha primeira intuição foi criar dois índices, um sobre o campo booleano e outro sobre o campo da data ... resultado, a query passou a levar mais de 3 segundos ... 5 vezes mais!!!
Fui melgar outra carola para me ajudar a perceber o fenómeno (thanks grande M. J.!), e após mais de 1 hora de andar às voltas, lá percebemos que o SQL Server estava a usar o índice do booleano para sacar TODOS os registos que satisfaziam a condição (900.000), e só depois usava o índice da  data para ordenar os registos e obter o primeiro.
Removendo os dois índices isolados e criando um índice conjunto dos dois campos, o SQL Server tem a inteligência suficiente para perceber que deve ordenar e filtrar ao mesmo tempo usando o índice, tornando a query muito mais eficiente. Resultado: 800 registos por minuto.
Portanto, atenção a esses índices sobre campos booleanos, especialmente quando esse campo é o único na claúsula where de uma query.

1 comment:

Acacio said...

Por acaso discuti isso com m MJ e lembro-me de ter lido um artigo em tempos sobre índices booleanos em SQL Server... Essencialmente só eram úteis para a situação em que tens uma grande disparidade na quantidade de verdadeiros e falsos e queres aceder aos de menor quantidade.

De toda a forma, que grande galo!