Je me demande quelles seraient les performances d'une requête, comme utiliser le mot-clé similaire et la carte générique comme valeur comparée à ne pas avoir de clause de la part du tout.
considère une clause de référence telle que "où un% similaire" ". Cela correspondra à toutes les valeurs possibles de la colonne 'A'. Comment cela se compare-t-il à ne pas avoir la clause WHERE? P>
La raison pour laquelle je demande est que j'ai une application dans laquelle l'utilisateur peut spécifier des valeurs à rechercher. Dans certains cas, l'utilisateur aimerait tous les résultats possibles. J'utilise actuellement une seule requête comme celle-ci: p> Les valeurs de '%' et "%" peuvent être fournies pour correspondre à toutes les valeurs possibles pour A et B. Ceci est pratique car je peux utiliser une seule requête nommée dans ma demande pour cela. Je me demande quelles sont les considérations de performance pour cela. L'optimiseur de requête réduit-il comme «%» pour simplement correspondre à tous? Je me rends compte que parce que j'utilise une requête nommée (déclaration préparée), cela peut également affecter la réponse. Je réalise que la réponse est probablement spécifique à la base de données. Donc, précisément, comment cela fonctionnerait-il dans Oracle, MS SQL Server et Derby. P> L'approche suppléante de remplacement de ce type serait d'utiliser 3 requêtes distinctes en fonction de l'utilisateur saisissant la carte générique. P> A est une requête générique: p> b est la requête générique: p> a et b est des cartes génériques: p> < Pré> xxx pré> pas de caractères génériques: p> ayant évidemment une seule requête est le plus simple et le plus facile à entretenir. Je préférerais utiliser une seule question si la performance sera toujours bonne. P> p>
11 Réponses :
Tout SGBD qui vaut son sel dépasserait La déclaration préparée ne doit pas faire une différence car elle devrait être transformée en réel em> sql avant qu'il ne reçoit Le moteur d'exécution. P> mais, comme pour toutes les questions d'optimisation, mesure, ne devinez pas em>! Les dabas existent parce qu'ils ajustement constamment les SGBD en fonction des données réelles (qui change au fil du temps). À un minimum nu, vous devriez faire du temps (et obtenir les plans d'exécution) pour toutes les variantes avec des données statiques appropriées pour voir s'il y a une différence. P> Je sais que les requêtes comme: p> sont optimisés pour supprimer l'ensemble de l'ensemble de la clause avant exécution (sur DB2 de toute façon et, avant de demander, la construction est utile où vous devez supprimer l'effet de la clause WHERE mais maintenez toujours l'espace réservé aux paramètres (en utilisant BIRT avec JavaScript afin de modifier les requêtes pour les caractères génériques)). P> P> comme '%' code> clauses avant même d'essayer d'exécuter la requête. Je suis assez certain que j'ai vu DB2 / Z faire cela dans ses plans d'exécution.
Je ne pense pas que cela soit vrai, surtout si la colonne comparée est nullable. Comme '%' ne devraient pas renvoyer ces lignes où la colonne est nulle, de sorte que les critères ne doivent donc pas les réintroduire soudainement aux résultats.
Le SGBD devrait (et est i> "devrait") être capable de dire si la colonne n'est pas nullable et ne pas optimiser. En tout état de cause, cela rendrait la question de l'OPS Moot, car ils ne seraient pas en mesure de le faire non plus.
Selon la structure de la manière dont le prédicat similaire est structuré et sur le terrain, vous pourriez avoir besoin d'une numérisation de table complète. Semantiquement un "%" pourrait impliquer une numérisation de table complète mais SQL Server fait toutes sortes d'optimisation en interne sur les requêtes. La question devient donc: Est-ce que SQL Server optimise sur un prédicat similaire formé avec '%' et le jette de la clause WHERE? P>
SQL Server verra généralement et le traiter comme p> ... et utilise heureusement un indice de recherche si nécessaire. Je dis 'généralement', parce que je l'ai vu ne pas faire cette simplification dans certains cas. P> Si quelqu'un essaie de faire: p> . ..anden une demande d'index sera essentiellement impossible. p> mais quelque chose d'aussi simple que: p> sera considéré comme équivalent à: p> < Pré> xxx pré> p>
DB2 (au moins) a le concept d'index inverse où '% Ville' est facilement optimisée (en stockant les valeurs inversées dans l'index et changeant en interne la requête à «Elliv%»). Vous pouvez imiter la même chose sur d'autres SGMS 'avec une colonne supplémentaire et des déclencheurs d'insérer / mettre à jour.
Bien sûr, mais alors% Ville% devient plus compliqué. Si vous recherchez des mots entiers, la recherche de FullText devient une option plus agréable.
+1 pour indiquer que comme '%' code> ne retournera que des lignes avec des valeurs non nulles.
Vous pouvez utiliser n'importe quelle analyse de requête The DBMS propose (par exemple, Expliquez Code>
pour mysql, SET WORSHPLAN_ALL sur CODE>
pour MS SQL (ou utilisez l'un des Autres méthodes ), Expliquer le plan pour code> pour oracle) pour voir comment la requête sera exécutée. P>
Et si une colonne a une valeur vide non nulle? Votre requête correspondra probablement à cela. P>
S'il s'agit d'une requête pour une application du monde réel, essayez d'utiliser les fonctionnalités d'indexation de texte gratuits de la plupart des bases de données SQL modernes. Les problèmes de performance deviendront insignifiants. P>
Un simple siénaque de Si (A b) rechercher A b sinon (a) rechercher A sinon b Rechercher b autre Dites à l'utilisateur qu'ils n'ont rien spécifié p>
est trivial pour maintenir et devient beaucoup plus facile à comprendre au lieu de faire des hypothèses sur l'opérateur similaire. Vous allez probablement faire cela dans l'interface utilisateur quand même lorsque vous affichez les résultats "Votre recherche d'une recherche x" ou "Votre recherche d'un B trouvé ..." p>
Je ne suis pas sûr de la valeur de l'utilisation d'une déclaration préparée avec le type de paramètres que vous décrivez. La raison en est que vous pourriez tromper l'optimiseur de requête dans la préparation d'un plan d'exécution qui serait complètement faux en fonction duquel des paramètres étaient «%». P>
Par exemple, si la déclaration a été préparée avec un plan d'exécution à l'aide de l'index sur la colonne A, mais le paramètre de colonne A s'est avéré '% "Vous pouvez rencontrer de mauvaises performances. P>
une clause où "comme"% "" comme le seul prédicat se comportera exactement de la même manière que la clause du tout. P>
Je voulais dire que cela se comportera de la même perspective de performance, mais je n'étais évidemment pas assez clair. En outre, cela n'est pas non plus vrai dans certains cas.
Derby propose également des outils permettant d'examiner le plan de requête réel utilisé. Vous pouvez donc exécuter des expériences à l'aide de Derby et examinez le plan de requête que Derby a choisi. Vous pouvez exécuter derby avec -dderby.language.logqueryplan = true et Derby écrira le plan de requête sur derby.log, ou vous pouvez utiliser la fonction RunTimestaticistique, comme décrit ici: http://db.apache.org/ederby/docs/10.5/TUning/ctundepth853133.html P >
Je ne suis pas sûr que Derby élimine le "%" comme "%" à l'avance, mais je ne pense pas non plus que la présence de cette clause introduira une grande partie du ralentissement de la vitesse d'exécution. P >
Je serais tout à fait intéressé de voir la sortie du plan de requête réelle que vous entrez dans votre environnement, avec et sans la clause de '%' en place. p>
Oracle 10Gr2 ne semble pas effectuer une optimisation spéciale pour cette situation, mais il reconnaît que, comme "%" exclut les nuls.
Plan hash value: 3733279756 -------------------------------------------------------------------------------- | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | -------------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | 1 | 10 | 3 (0)| 00:00:01 | | 1 | SORT AGGREGATE | | 1 | 10 | | | |* 2 | TABLE ACCESS FULL| LIKE_TEST | 1000 | 10000 | 3 (0)| 00:00:01 | -------------------------------------------------------------------------------- Predicate Information (identified by operation id): --------------------------------------------------- 2 - filter("COL1" IS NOT NULL)
Un aspect que je pense manque à la discussion est le fait que l'OP souhaite utiliser une déclaration préparée. Au moment où la déclaration est préparée, la base de données / optimiseur ne sera pas en mesure de déterminer les simplifications dont les autres ont mentionné et ne pourront donc pas optimiser le donc: p>
A comme '%' code> comme le réel la valeur ne sera pas connue à la préparation du temps. p>
J'espérais qu'il y aurait une réponse de manuel à cela, mais il semble que cela varie en grande partie avec différents types de base de données. La plupart des réponses ont indiqué que je devrais exécuter un test de sorte que c'est exactement ce que j'ai fait.
Mon application ciblait principalement les bases de données Derby, MS SQL et Oracle. Depuis que Derby peut être exécuté intégré et est facile à configurer, j'ai testé la performance à ce début. Les résultats étaient surprenants. J'ai testé le pire des cas de scénario contre une table assez grande. J'ai exécuté le test 1000 fois et ai fait la moyenne des résultats. P>
Query 1: P>
SELECT * FROM TableName WHERE a LIKE ? AND b LIKE ?
Je ne peux que recommander de le tester. Mais j'essaierais de rester à des requêtes simples. Ne surchargez pas la surcommande, faites deux séparément. A MON HUMBLE AVIS.
Je recommande vivement de lire l'article d'Erland sur les conditions de recherche dynamiques. C'est assez long mais je pense que cela vous donnera une perspicacité très sérieuse et utile sur le sujet. SOMMARSKOG.SE/DYN-SEARCH-2005.HTML
"Je me demande quelle serait la performance d'une requête". Réponse facile à cela est: Exécutez des tests.