Pergunta

Estou tendo um problema de desempenho muito particular no trabalho!

No sistema que estamos usando, há uma tabela que contém informações sobre o processo atual de fluxo de trabalho. Um dos campos segura uma planilha que contém metadados sobre o processo (não me pergunte por que !! e não, eu não posso mudar !!)

O problema é que essa planilha é armazenada em um campo de imagem em um SQL Server 2005 (dentro de um banco de dados definido com compatibilidade SQL 2000).

Atualmente, esta tabela possui linhas de 22k+ e até mesmo uma consulta simples como esta:

SELECT TOP 100 *
  FROM OFFENDING_TABLE

Leva 30 segundos para recuperar os dados no analisador de consultas.

Estou pensando em atualizar a compatibilidade com o SQL 2005 (uma vez que fui informado de que o aplicativo pode lidar com isso).

A segunda coisa que estou pensando é mudar o tipo de dados da coluna para varbinary(max) Mas não sei se isso afetará o aplicativo.

Outra coisa que estou considerando é usar sp_tableoption Para definir o large value types out of row para 1 Como é atualmente 0, mas não tenho informações se isso melhorará o desempenho.

Alguém sabe como melhorar o desempenho em esse cenário?


Editado para esclarecer

Meu problema é que não tenho controle sobre o que o aplicativo pede ao servidor SQL e fiz alguma reflexão sobre ele (o aplicativo é um site .NET 1.1) e ele usa o campo ofensivo para algumas coisas internas que eu não tenho ideia o que é isso.

Preciso melhorar o desempenho geral desta tabela.

Foi útil?

Solução

Eu recomendo que você veja a saúde do layout da mesa ofensiva:

select * from sys.dm_db_index_physical_stats(
       db_id(), object_id('offending_table'), null, null, detailed);

As coisas também procuram. Dicas como alta fragmentação, ou um alto número de registros fantasmas, ou uma página baixa usada, indicam problemas e as coisas podem ser melhoradas um pouco apenas reconstruindo o índice (ou seja, a tabela) do zero:

ALTER INDEX ALL ON offending_table REBUILD;

Estou dizendo isso, considerando que você não pode alterar a tabela nem o aplicativo. Se você puder alterar a tabela e o aplicativo, o conselho que você já recebeu é um bom conselho (não use '*', não 'selecione W/OA Condition, use o tipo varbinário mais recente (max) etc etc) .

Eu também examinaria a vida útil média da página em contadores de desempenho para entender se o sistema está faminto pela memória. A partir da sua descrição dos sintomáticos, o sistema parece encadernado, o que me leva a pensar que há pouco cache de páginas acontecendo, e mais RAM pode ajudar, além de um subsistema mais rápido de IO. Em um sistema SQL 2008, eu também sugeriria ativar a compactação da página, mas em 2005 você não pode.
E, apenas para ter certeza, verifique se as consultas não estão bloqueadas pela disputa do próprio aplicativo, ou seja. A consulta não gasta 90% desses 30 segundos aguardando uma trava de linha. Olhe para sys.dm_exec_requests Enquanto a consulta estiver em execução, consulte Wait_time, Wait_Type e Wait_Resource. É Pageiolatch_xx? Ou é uma fechadura? Além disso, como está o sys.dm_os_wait_stats No seu servidor, quais são os principais motivos de espera?

Outras dicas

Em primeiro lugar - Nunca faça um SELECT * no código de produção - relatórios ou não.

Você tem três opções básicas:

  • Mova esse campo de blob para uma tabela separada, se nem sempre for necessária; Provavelmente não é prático, pois você menciona que não pode mudar o esquema

  • tenha mais cuidado com o seu SELECT Declarações para selecionar apenas os campos que você realmente precisa - e omitir o campo BLOB

  • Veja se você pode limitar sua consulta para incluir um WHERE Cláusula e encontre uma maneira de otimizar o plano de consulta, por exemplo, adicionando um índice adequado à tabela (se puder)

Não há switch "Make This Faster That mais rápido" - mas você pode otimizar sua consulta ou otimizar o layout da tabela. Ambos ajudam. Se você não pode mudar nada - nem o layout da tabela, nem adicionar um índice, nem alterar as consultas, você terá dificuldade em otimizar qualquer coisa, tenho medo ....

Apenas alterar o campo para varbinário (Max) não mudará nada - nenhuma melhoria de desempenho é esperada apenas da alteração do tipo de dados.

Uma resposta curta é fazer apenas selecionar em várias linhas quando os campos retornados não incluem o campo de imagem ofensiva, ou seja, não seleção *. Se você deseja o valor do campo da imagem, recupere-o caso a caso.

Definir os grandes tipos de valor fora da opção de linha deve definitivamente ajudar o desempenho. O tamanho da linha será significativamente menor, o SQL Server pode fazer muito menos leituras físicas para passar pela tabela.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top