|
Publicité ' | ||||||||||||||||||||||||
|
|
#1 | ||||
|
Membre chevronné
![]() ![]() Inscription : juillet 2006 Messages : 1 194 ![]() |
Bonjour.
Je m'interroge devant certaines performance d'un de mes queries. J'ai une table qui n'a pour seul index sa clé primaire composée d'un entier (IdClub) et d'un nvarchar(250) (FilePath). J'aimerais retrouvé dans ma table toutes les lignes où IdClub correspond à un certain paramètre entier et où FilePath est le début (ou la totalité) d'un certain paramètre chaîne de caractères. Cela donne quelque chose comme ceci : Code :
J'aimerais évidement tirer un meilleur parti de l'index, mais je ne trouve pas d'écriture permettant de le faire. Par exemple, ceci est un non-sens: Code :
|
||||
|
|
00
|
|
|
#2 |
![]() ![]() ![]() Nicolas SouquetAdministrateur de base de données Inscription : janvier 2005 Messages : 4 669 ![]() |
Bonjour,
Cela ne serait-il pas du au IN ? @++
__________________
En bases de données relationnelles SQL, il n'y a ni tableaux, ni enregistrements, ni champs: il y a des tables, des lignes et des colonnes. Blog | Profil| Consulter ou télécharger les fichiers d'aide de SQL Server, des versions 2000 à 2012 |
|
00
|
|
|
#3 |
![]() ![]() ![]() David BARBARINExpert SQL Server Inscription : août 2005 Messages : 3 724 ![]() |
Probablement le IN dans votre cas comme le dit Elsuket.
Postez votre plan d'exécution. ++ |
|
00
|
|
|
#4 | ||
|
Membre chevronné
![]() ![]() Inscription : juillet 2006 Messages : 1 194 ![]() |
Non le résultat est pareil avec = même sans OR.
Code :
Comment poster un plan d’exécution ? |
||
|
|
00
|
|
|
#5 |
![]() ![]() ![]() Nicolas SouquetAdministrateur de base de données Inscription : janvier 2005 Messages : 4 669 ![]() |
Quel est le nombre de lignes de la table et le nombre de valeurs distinctes de la colonne IdClub ?
Pour le plan d'exécution, je n'ai pas trouvé comment attacher un document à un post. Au pire, postez le document XML entier. @++
__________________
En bases de données relationnelles SQL, il n'y a ni tableaux, ni enregistrements, ni champs: il y a des tables, des lignes et des colonnes. Blog | Profil| Consulter ou télécharger les fichiers d'aide de SQL Server, des versions 2000 à 2012 |
|
00
|
|
|
#6 | ||
|
Membre chevronné
![]() ![]() Inscription : juillet 2006 Messages : 1 194 ![]() |
Il y a 60004 lignes dans la table (table remplie artificiellement).
Et 2 valeurs distincte pour IdClub. Voici les plans (on y voit que l'index n'est pas exploité sur la chaîne de caractères) : Code :
|
||
|
|
00
|
|
|
#7 | ||
|
Membre Expert
![]() Sylvain DevidalChef de projets Générix Inscription : février 2010 Messages : 1 062 ![]() |
Juste comme ça, de ce que j'ai compris, vous recherchez si la valeur de votre champ est présente dans le critère de recherche.
Donc la comparaison qui utilise un LIKE : Peut aussi s'écrire : Code :
Plus intéressant, si par heureux ahsard votre champ fait toujours la même taille, vous pouvez tronquer 'toto' à la source, avant de l'envoyer à votre requête, et ainsi transformer votre like ou left en égalité stricte. |
||
|
|
00
|
|
|
#8 | ||
|
Membre Expert
![]() Sylvain DevidalChef de projets Générix Inscription : février 2010 Messages : 1 062 ![]() |
Voici le résultat de mes tests :
Code :
Le premier SELECT fait un "clustered index seek", et le second un "clustered index scan". Le premier (celui que je propose donc) semble plus rapide. Cependant, je n'arrive pas à lire précisément les différences entre les deux plans d'exécuction... En tout cas, je ne m'explique pas un truc : au boulot, j'ai une brouette qui met à peut près 20 secondes à ouvrir le bloc note... et pourtant les deux requêtes sont absolument instantannées. Je ne comprends pas votre contre-performance avec seulement 64 000 lignes ! Même si vos filepath sont plus longs et ont plus de caractères que les miens, ça me semble quand même très étrange... |
||
|
|
00
|
|
|
#9 |
|
Membre Expert
![]() Sylvain DevidalChef de projets Générix Inscription : février 2010 Messages : 1 062 ![]() |
je viens de refaire le test avec 1 000 000 lignes, et sur ma brouette, c'est toujours aussi rapide (moins de 1 seconde pour retrouver 0 ou n lignes, quelle que soit la méthode utilisée).
Tu peux poster le script de ton protocole de test ? -- Edit : Et je confirme que ma syntaxe est plus performance (enfin... presque) : sur un lot avec les deux requêtes, ma syntaxe consomme 48% du lot, et la vôtre 52%. |
|
|
00
|
|
|
#10 | ||
|
Membre chevronné
![]() ![]() Inscription : juillet 2006 Messages : 1 194 ![]() |
Ce query doit être exécuté plusieurs milliers de fois de façon consécutive.
À l'unité c'est trois fois rien, certe mais par batch de 1000, le problème de performance devient conséquent. Batch de 100: Code :
|
||
|
|
00
|
|
|
#11 | ||
|
Membre chevronné
![]() ![]() Inscription : juillet 2006 Messages : 1 194 ![]() |
Voici le query qui fait ce que je souhaite qui soit fait :
Code :
Comme je le disais, la complexité de ce query doit choquer (qui requiert une table numérique). Alors, si moi je peux tirer parti de l'index avec un query aussi tiré par les cheveux que ça, il existe peut-être une méthode plus concise prévue par M$ ou découverte par les utilisateurs. Merci à ceux qui pourraient me mettre sur une piste. |
||
|
|
00
|
|
|
#12 |
|
Membre Expert
![]() Sylvain DevidalChef de projets Générix Inscription : février 2010 Messages : 1 062 ![]() |
Je constate que dans la query "tirée par les cheveux", il n'y a plus de like.
C'est conforme à mon analyse initiale : étrange de faire un LIKE d'un champ dans une constante. Avez-vous testé ma suggestion ? J'ai bien l'impression que ça fait à peu de chose près la même chose. Et le plan d'exécution n'étant pas le même chez moi (d'un index scan, on passe à un index seek, soit une réelle utilisation de l'index) il se pourrait bien que votre solution réside dans ma requête. |
|
|
00
|
|
|
#13 | |
|
Membre chevronné
![]() ![]() Inscription : juillet 2006 Messages : 1 194 ![]() |
Citation:
Je serai ravis que vous le fassiez tourner sur votre machine et nous faire part de vos résultats afin d'avoir le cœur net (sait on jamais) des choses qui ont été discutée. |
|
|
|
00
|
|
|
#14 |
|
Membre Expert
![]() Sylvain DevidalChef de projets Générix Inscription : février 2010 Messages : 1 062 ![]() |
Je viens de faire tourner le bench des 100 itérations.
Chez moi ça dure 9 secondes, et ma requpête (après suppression du ORDER BY, pour la mettre sur un pied d'égalité avec la vôte) dure environ 30% moins longtemps (3701000 µs contre 5138000 µs). En revanche, je ne peux pas tester votre requête qui va plus vite : vous utilisez une table et des fonctions dont je n'ai pas connaissance. |
|
|
00
|
|
|
#15 | ||
|
Membre Expert
![]() Sylvain DevidalChef de projets Générix Inscription : février 2010 Messages : 1 062 ![]() |
En reprenant le concept de ta super requête, je vais... "infiniment" plus vite en utilisant un petit bloc de T-SQL :
Code :
La quatrième requête (T-SQL) recherche sur l'égalité stricte pour toutes les sous-chaines en partant de la chaine originale, puis en enlevant un caractère jusqu'à ce qu'on trouve une ligne) : instantanné (0 µs en cumulé) En tout cas, je ne comprends pas comment SQL Server fait sont like... Parceque mon T-SQL fait rigoureusement ce que fait un LIKE ! |
||
|
|
00
|
|
|
#16 | ||||
![]() ![]() |
J'ai implémenté votre algorithme astucieux SergeJack, mais sur ma machine le like a des performances comparables légèrement plus rapide !
Il s'agit d'un serveur qui tourne sur SQL-Server 2005. En repartant de la table test de StringBuilder, je rajoute la table Tally que je limite à 250 entrées pour ce sujet : Code :
Code :
__________________
Email : http://scr.im/waldar |
||||
|
00
|
|
|
#17 | |||
![]() ![]() ![]() David BARBARINExpert SQL Server Inscription : août 2005 Messages : 3 724 ![]() |
Citation:
++ |
|||
|
00
|
|
|
#18 |
|
Membre Expert
![]() Sylvain DevidalChef de projets Générix Inscription : février 2010 Messages : 1 062 ![]() |
Waldar > Refaites votre bench en réactivant la première requête, et en virant le "order by". Vous verrez qu'elle est bien plus rapide que les autres requêtes. ce qui plopmbe tout, c'est le order by, je me demande bien pour quoi d'ailleurs. N'étant pas présent sur les autres requête, il faut l'enlever pour que le test soit significatif.
|
|
|
00
|
|
|
#19 | |||||
|
Membre chevronné
![]() ![]() Inscription : juillet 2006 Messages : 1 194 ![]() |
Citation:
Mais jamais je n'ai obtenu des résultats allant dans ce sens. Par exemple, mes 2 derniers runs : Code :
Moi j'ai 99918 lignes. - Dans tous mes tests : l'index est utilisé, mais uniquement pour la correspondance du IdClub. Son utilisation est donc partielle et insuffisante. Si vous obtenez autre chose, est-ce que vous pourriez postez vos excecution plans ? |
|||||
|
|
00
|
|
|
#20 | ||||
![]() ![]() |
Citation:
Sur 5 * 1000 exécutions : Exec 1 42000 66000 39000 Exec 2 21000 48000 42000 Exec 3 33000 39000 39000 Exec 4 36000 60000 12000 Exec 5 27000 66000 18000 Citation:
Code :
Je les joins à ce message.
__________________
Email : http://scr.im/waldar |
||||
|
00
|
Copyright © 2000-2012 - www.developpez.com