Performances SQL LIKE avec uniquement le caractère générique (%) en tant que valeur
Je me demande ce que les performances d'une requête serait en utilisant le mot clé LIKE et le caractère générique de la valeur par rapport à ne pas avoir de clause where.
Envisager une clause where telles que "d'OÙ un LIKE '%'". Cela va correspondre à toutes les valeurs possibles de la colonne "a". Comment cela se compare à ne pas avoir la clause where.
La raison pour laquelle je demande c'est que j'ai une application dans laquelle il y a quelques champs que l'utilisateur peut spécifier des valeurs pour effectuer une recherche. Dans certains cas, l'utilisateur souhaite que tous les résultats possibles. Je suis actuellement en utilisant une seule requête comme ceci:
SELECT * FROM TableName WHERE a LIKE ? AND b LIKE ?
Les valeurs de " % " et " % " peut être fourni pour correspondre à toutes les valeurs possibles pour a et b. C'est pratique car je peux utiliser une seule requête nommée dans ma demande pour cela. Je me demande ce que les considérations relatives aux performances sont pour cela. L'optimiseur de requête de réduire LIKE '%' pour simplement correspondre à tous? Je me rends compte que parce que je suis en utilisant une requête nommée (déclaration préparée à l'avance), qui peut également affecter la réponse. Je me rends compte que la réponse est probablement la base de données spécifique. Donc, précisément comment ce travail dans Oracle, MS SQL Server et les Derby.
L'autre approche serait d'utiliser les 3 requêtes distinctes en fonction de l'utilisateur d'entrer le générique.
Un est générique requête:
SELECT * FROM TableName WHERE b LIKE ?
B est générique requête:
SELECT * FROM TableName WHERE a LIKE ?
A et B sont des jokers:
SELECT * FROM TableName
Aucun des caractères génériques:
SELECT * FROM TableName WHERE a LIKE ? AND b LIKE ?
Évidemment le fait d'avoir une seule requête est la plus simple et la plus facile à maintenir. Je préfère utiliser juste une requête si les performances seront encore bonnes.
source d'informationauteur Chris Dail
Vous devez vous connecter pour publier un commentaire.
SQL Server généralement
et de la traiter comme
...et heureusement utilisation d'un index de recherche le cas échéant. Je dis "en général", parce que je l'ai vu ce n'est que la simplification dans certains cas.
Si quelqu'un essaie de faire:
...puis d'un index de recherche sera essentiellement impossible.
Mais quelque chose d'aussi simple que:
sera considérée comme équivalente à:
Vous pouvez utiliser n'importe quel requête analyse le SGBD (par exemple,
EXPLIQUER
pour MySQL,SET SHOWPLAN_ALL on
pour MS SQL (ou utilisez l'un des d'autres méthodes),EXPLAIN PLAN FOR
pour Oracle) pour voir comment la requête sera exécutée.J'espérais qu'il y aurait un manuel de répondre à cela, mais on dirait qu'elle sera largement varier selon les types de base de données. La plupart des réponses indiquent que je dois exécuter un test de sorte que c'est exactement ce que j'ai fait.
Mon application cible principalement le Derby, MS SQL et des bases de données Oracle. Depuis le derby peut être exécuté intégré et facile à mettre en place, j'ai testé les performances sur le premier. Les résultats sont surprenants. J'ai testé le pire des cas à l'encontre d'une assez grande table. J'ai couru le test de 1000 fois et la moyenne des résultats.
Requête 1:
Requête 2 (Avec des valeurs de a="%" et b="%"):
Requête 1 temps moyen: 178ms
Requête 2 durée moyenne: 181ms
De sorte que les performances sur la derby est presque le même entre les deux requêtes.
Un SGBD qui vaut son sel dépouiller
LIKE '%'
clauses avant même d'essayer d'exécuter la requête. Je suis assez certain que je l'ai vu DB2/z ce faire, dans ses plans d'exécution.La déclaration ne devrait pas faire une différence, car il devrait être transformé en réel SQL avant que le moteur d'exécution.
Mais, comme avec toutes les questions d'optimisation, mesure, n'essayez pas de deviner! Administrateurs de bases de données existent, car ils ne cessent de régler le SGBD basées sur des données réelles (qui change au fil du temps). Au minimum, vous devriez de temps (et d'obtenir les plans d'exécution) pour toutes les variantes convenables données statiques pour voir si il y a une différence.
Je sais que les requêtes comme:
sont optimisé pour enlever la totalité de la clause where avant l'exécution (DB2 et de toute façon, avant de vous demander, la construction est utile lorsque vous avez besoin de supprimer l'effet de la clause where, mais encore de maintenir le paramètre de l'espace réservé (à l'aide de BIRT avec Javascript pour modifier les requêtes pour des caractères génériques)).
Derby propose également des outils permettant d'examiner le plan de requête qui a été utilisé, de sorte que vous pouvez exécuter à l'aide des expériences Derby et de regarder le plan de requête Derby choisi. Vous pouvez exécuter Derby avec -Dderby.de langue.logQueryPlan=true, et le Derby va écrire le plan de requête de derby.journal, ou vous pouvez utiliser le RUNTIMESTATISTICS installation, comme décrit ici: http://db.apache.org/derby/docs/10.5/tuning/ctundepth853133.html
Je ne suis pas sûr si le Derby de bande la UNE LIKE '%' à l'avance, mais je ne pense pas que la présence de cette clause va introduire beaucoup de ralentissement de la vitesse d'exécution.
Je serais assez intéressé de voir le plan de requête de sortie que vous obtenez dans votre environnement, avec et sans la UNE LIKE ' % " clause en place.
Oracle 10gR2 ne semble pas effectuer une spéciale optimisation de cette situation, mais il reconnaît que LIKE ' % exclut les valeurs null.
... donner ...
... et ...
... et ...
Note la cardinalité (lignes) sur la TABLE d'ACCÈS COMPLET de la ligne de
En fonction de la façon dont le prédicat LIKE est structuré et sur le terrain, vous faites des tests, vous pourriez avoir besoin d'un full table scan. Sémantiquement un '%' peut sous-entendre un full table scan mais Sql Server ne toutes sortes d'optimisation en interne sur des requêtes. Ainsi, la question devient: Est-Sql Server optimiser sur un prédicat LIKE formé avec " % " et le jette hors de la clause where?
Un aspect qui, je pense, est absent de la discussion est le fait que l'OP veut utiliser une instruction préparée. Au moment où la déclaration est établie, la base de données/de l'optimiseur ne sera pas en mesure de travailler sur les simplifications d'autres l'ont mentionné et ne sera donc pas en mesure d'optimiser loin le
a like '%'
que la valeur réelle ne sera pas connu à préparer le temps.Donc:
Que si une colonne a une valeur non nulle de la valeur à blanc? Votre requête sera probablement le match.
Si c'est une requête pour une application du monde réel puis essayez d'utiliser le libre indexation de texte intégral les fonctions de la plupart modernes, les bases de données sql. Les problèmes de performances deviennent insignifiants.
Simple si l'instruction de
si (A B)
la recherche d'un b
d'autre (Un)
recherche un
d'autre B
recherche b
d'autre
dire à l'utilisateur qu'ils ne spécifiez rien
est facile à maintenir, et devient beaucoup plus facile à comprendre au lieu de faire des hypothèses sur l'opérateur LIKE. Vous êtes probablement va le faire dans l'INTERFACE utilisateur de toute façon, lorsque vous affichez les résultats de Votre recherche pour Un x" ou "Votre recherche d'Un B trouvé..."
Je ne suis pas sûr de la valeur de l'aide d'une requête préparée avec le type de paramètres que vous décrivez. La raison en est que vous avez peut tromper l'optimiseur de requête dans la préparation d'un plan d'exécution qui serait tout à fait tort en fonction des paramètres ont été '%'.
Par exemple, si l'énoncé ont été préparés avec un plan d'exécution à l'aide de l'index sur la colonne A, mais le paramètre de la colonne A s'est avéré être '%', vous pouvez rencontrer des problèmes de performances.
une clause where avec "like" % '" en tant que seul prédicat va se comporter exactement la même que pas de clause where.