2010-09-29 6 views
0

J'ai une base de données contenant des adresses, une adresse par ligne. Contient chaque adresse au Royaume-Uni, donc ~ 28 millions de lignes. L'une des colonnes est «Street», que j'utilise pour effectuer des recherches. J'ai un index non unique, non clusterisé sur cette colonne. J'ai cependant des incohérences avec les vitesses de recherche.TSQL Recherche dans une grande base de données indexée à l'aide de LIKE

select * from Postcodes where Street = 'London Road' 

Prend ~ 1s pour s'exécuter.

select * from Postcodes where Street like'London Road%' 

Cela prend également environ une seconde. Toutefois, cette déclaration, bien qu'apparemment identique à la seconde, prend environ 40 secondes à s'exécuter.

Je suis complètement à la perte de ce qui cause cette différence de vitesse. Des idées?

+0

Quel est le type de données, rue s'il vous plaît? – gbn

Répondre

1

Le problème est que MSSQLServer ne peut pas savoir à l'avance ce qui va être contenu dans la variable @Street, donc il ne peut pas utiliser un index sur la colonne Street.

Si votre déclaration est:

select * from Postcodes where Street = 'London'; 
select * from Postcodes where Street like 'London Road%'; 

Il peut utiliser un index sur la colonne Street car il connaît la chaîne commence par London.

Si votre déclaration est:

select * from Postcodes where Street like @VariableName; 

Il ne peut pas utiliser l'index car avec cette déclaration, vous devriez être en mesure de le faire:

select * from Postcodes where Street like 'London%'; 
select * from Postcodes where Street like '%London%'; 

Ou toute autre valeur valide pour VariableName. C'est un problème typique dans les déclarations précompilées. Ce que vous pouvez faire est d'utiliser la chaîne directement, ou ne pas utiliser de paramètres et de changer votre instruction pour être une instruction SQL dynamique dans TSQL.

+0

Ce n'est pas la raison. Le problème est qu'il n'utilise pas l'index plus étroit car il ne renifle pas la valeur de la variable pour déterminer la sélectivité. Il peut toujours faire une recherche de plage pour un premier caractère générique. Juste le début et la fin de la gamme couvrent l'ensemble de l'indice. –

1

Si vous savez à l'avance que vous n'aurez jamais leader wildcards et sont sur SQL Server 2008, vous pouvez essayer

declare @Street varchar(20) = 'London Road%' 
SELECT * FROM 
Postcodes WITH (FORCESEEK) 
where Street like @Street 
Questions connexes