Je voudrais vous demander votre avis quant à l'implémentation d'un formulaire de recherche filtré. Imaginons le cas suivant:
- 1 grande table avec beaucoup de colonnes
- Il pourrait être important de dire que ce serveur SQL
Vous devez implémenter un formulaire pour rechercher des données dans ce tableau, et dans ce formulaire, vous aurez plusieurs cases à cocher qui vous permettront de personnaliser cette recherche.
Maintenant, ma question ici est laquelle parmi les suivantes devrait être la meilleure façon de mettre en œuvre la recherche?
Créez une procédure stockée avec une requête à l'intérieur. Cette procédure stockée vérifiera si les paramètres sont donnés par l'application et dans le cas où ils ne sont pas donnés, un caractère générique sera mis dans la requête.
Créez une requête dynamique, qui est construite en fonction de ce qui est donné par l'application.
Je pose cette question parce que je sais que SQL Server crée un plan d'exécution lorsque la procédure stockée est créée, afin d'optimiser ses performances, mais en créant une requête dynamique à l'intérieur de la procédure stockée, sacrifierons-nous l'optimisation obtenue par le plan d'exécution?
Veuillez me dire quelle serait la meilleure approche à votre avis.
Réponses:
Vous voudrez peut-être consulter la réponse à cette question similaire ici: /programming/11329823/add-where-clauses-to-sql-dynamically-programmatically
Nous avons constaté qu'un SPROC qui prend un tas de paramètres facultatifs et implémente le filtre comme ceci:
mettra en cache le premier plan d'exécution avec lequel il est exécuté (par exemple
@optionalParam1 = 'Hello World', @optionalParam2 = NULL
), mais fonctionnera misérablement si nous lui transmettons un ensemble différent de paramètres facultatifs (par exemple@optionalParam1 = NULL, @optionalParam2 = 42
). (Et évidemment, nous voulons les performances du plan mis en cache, il enWITH RECOMPILE
va de même)L'exception ici est que s'il y a AUSSI au moins un filtre OBLIGATOIRE sur la requête qui est HAUTEMENT sélectif et correctement indexé, en plus des paramètres facultatifs, alors le PROC ci-dessus fonctionnera correctement.
Cependant, si TOUS les filtres sont facultatifs, la vérité plutôt horrible est que SQL dynamique paramétré fonctionne réellement mieux (à moins que vous n'écriviez N! PROCS statiques différents pour chaque permutation de paramètres facultatifs).
Le SQL dynamique comme ci-dessous créera et mettra en cache un plan différent pour chaque permutation des paramètres de requête, mais au moins chaque plan sera `` adapté '' à la requête spécifique (peu importe qu'il s'agisse d'un SQL PROC ou Adhoc - comme tant qu'il s'agit de requêtes paramétrées, elles seront mises en cache)
D'où ma préférence pour:
etc. Peu importe si nous passons des paramètres redondants dans sp_executesql - ils sont ignorés. Il convient de noter que les ORM tels que Linq2SQL et EF utilisent SQL dynamique paramétré de manière similaire.
la source
Commencez par ce que vous pensez être plus facile à mettre en œuvre (je suppose que l'option 2). Mesurez ensuite les performances des données du monde réel. Ne commencez l'optimisation qu'en cas de besoin, pas avant.
Soit dit en passant, selon la complexité de vos filtres de recherche, votre tâche peut ne pas être facilement résolue sans SQL dynamique. Ainsi, même lorsque vous utilisez une procédure stockée, cela n'augmentera probablement pas les performances, comme vous le soupçonnez déjà. D'un autre côté, si cela aide, il existe plusieurs types d'indices (voir http://www.simple-talk.com/sql/performance/controlling-execution-plans-with-hints/ ) que vous pouvez ajouter à un SQL requête, dynamique ou non, pour aider SQL Server à optimiser son plan d'exécution.
la source