SQL Compact: Sim, a performance conta muito

Há tempos foi reportado que num dos nossos clientes da nossa solução de pré/auto-venda, o carregamento de uma lista com 60 a 70 registos demorava mais de 5 minutos, enquanto noutros clientes, com o mesmo volume de informação não demorava mais de uns breves segundos. A operação em causa dependia de uma consulta à base de dados no PDA que continha múltiplos JOIN, sobre um comando preparado, e a diferença entre clientes também poderia estar relacionada com os equipamentos utilizados, pois a tal operação de ‘5 minutos’ com a mesma base de dados demorava ‘apenas’ 40 segundos no meu emulador.

Para fazer o tunning à instrução, abri o SQL Server Management Studio, e estudei o Execution Plan da mesma, o que me foi dando ideias para índices a criar, mas sem que tal tivesse um impacto significativo em termos de performance. Aí vi que tinha que mudar a instrução e comecei a pensar como fazê-lo, pois era importante obter a informação das tais tabelas ligadas de uma só vez, mas identifiquei uma tabela de lookup, e tirei-a da instrução SQL, menos um JOIN portanto, e automaticamente o comando passou a ser executado quase instantaneamente. Como a tal tabela era importante, decidi pré-carregá-la numa colecção do tipo key, value, e a cada registo consultava essa colecção para recuperar o valor que necessitava.

Tudo embalado de novo (alteração ao comando, carregamento da lista e novos índexes), no PDA do cliente a tal operação que demorava mais de 5 minutos passou a ser executada em entre 1 e 2 segundos!

Hoje dei com esta pérola no fórum da MSDN dedicado ao SQL Compact, um tipo que tinha uma instrução tão simples como:

SELECT TOP(1) SysDate FROM Violator ORDER BY SysDate Desc

em que a tabela em causa tinha um index criado para a coluna em causa com ordem descendente. Ao executar a instrução no emulador demorava cerca de 35 segundos, o que para ele era inaceitável, e ao analisar o Execution Plan do comando no SQL Server Management Studio, concluíu que o SQL Compact estava a fazer um INDEX SCAN em vez de um INDEX SEEK, que se esperaria que fosse mais performante. O EricEJ, um MVP de SQL Server Compact, sugeriu-lhe uma pequena modificação à instrução, acrescentando-lhe um WHERE inócuo…

SELECT TOP(1) SysDate FROM Violator WHERE SysDate < GETDATE() ORDER BY SysDate Desc

… e automaticamente o comando passou a ser executado de forma muito mais rápida no emulador!

Conclusão

O Query Processor (QP) do SQL Compact tem o seu quê de feminino, é difícil compreender as suas decisões, e mesmo quando achamos que o conhecemos bem, lá aparece uma situação nova a mostrar-nos o contrário, e temos de usar de truques para o convencer a fazer o que queremos :)

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>