2010-09-23 30 views
10

Dans le passé, j'ai noté des performances terribles lors de l'interrogation d'une colonne varbinary (max). C'est compréhensible, mais cela semble aussi arriver en vérifiant si c'est nul ou non, et j'espérais que le moteur prendrait plutôt quelques raccourcis.Stratégies pour vérifier ISNULL sur les champs varbinary?

select top 100 * from Files where Content is null 

Je suppose que c'est lent parce qu'il est

  1. Ayant besoin pour tirer le binaire tout sur et
  2. Ce n'est pas indexé (varbinary ne peut pas faire partie d'un indice normal)

This question semble être en désaccord avec mon principe de lenteur ici, mais je semble avoir des problèmes de performance avec des champs binaires à maintes reprises.

Une solution possible, je pensais est de faire une colonne calculée qui est indexé:

alter table Files 
add ContentLength as ISNULL(DATALENGTH(Content),0) persisted 

CREATE NONCLUSTERED INDEX [IX_Files_ContentLength] ON [dbo].[Files] 
(
    [ContentLength] ASC 
) 

select top 100 * from Files where ContentLength = 0 

Est-ce une stratégie valide? Quelles sont les autres façons d'interroger efficacement lorsque des champs binaires sont impliqués?

Répondre

8

Je pense que c'est lent car la colonne varbinary n'est pas (et ne peut pas être) indexée. Par conséquent, votre approche pour utiliser une colonne calculée (et indexée) est valide.

Cependant, j'utiliserais ISNULL(DATALENGTH(Content), -1) à la place, de sorte que vous puissiez distinguer entre la longueur 0 et NULL. Ou utilisez simplement DATALENGTH(Content). Je veux dire, Microsoft SQL Server n'est pas Oracle où une chaîne vide est la même que NULL.

2

Nous avons rencontré un problème similaire lors de la recherche de lignes où une valeur varbinary n'était pas nulle. Pour nous, la solution consistait à mettre à jour les statistiques de la base de données:

exec sp_updatestats 

Après cela, les requêtes s'exécutaient beaucoup plus rapidement.