Un de mes collègues a nommé une procédure stockée dans notre base de données SQL Server 2008 R2 sp_something
. Quand j'ai vu cela, j'ai immédiatement pensé: "C'est FAUX!" et a commencé à chercher dans mes signets cet article en ligne qui explique pourquoi il est faux, afin que je puisse fournir une explication à mon collègue.
Dans l'article (de Brian Moran ), il est expliqué que, si un préfixe sp_ est attribué à la procédure stockée, SQL Server recherche dans la base de données master un plan compilé. sp_sproc
SQL Server recompilera la procédure ( car elle n’y réside pas) (et nécessite un verrou de compilation exclusif pour cela, ce qui entraîne des problèmes de performances).
L'exemple suivant est donné dans l'article pour montrer la différence entre deux procédures:
USE tempdb;
GO
CREATE PROCEDURE dbo.Select1 AS SELECT 1;
GO
CREATE PROCEDURE dbo.sp_Select1 AS SELECT 1;
GO
EXEC dbo.sp_Select1;
GO
EXEC dbo.Select1;
GO
Vous exécutez cette opération, puis ouvrez le profileur (ajoutez l' SP:CacheMiss
événement Procédures stockées -> ) et exécutez à nouveau les procédures stockées. Vous êtes censé voir une différence entre les deux procédures stockées: la sp_Select1
procédure stockée générera un SP:CacheMiss
événement de plus que la Select1
procédure stockée (l'article fait référence à SQL Server 7.0 et SQL Server 2000 ).
Lorsque j'exécute l'exemple dans mon environnement SQL Server 2008 R2, j'obtiens le même nombre d' SP:CacheMiss
événements pour les deux procédures (à la fois dans tempdb et dans une autre base de données de test).
Alors je me demande:
- Puis-je avoir fait quelque chose de mal dans l'exécution de l'exemple?
L'sproc sp_something
adagium " ne nommez-vous pas un utilisateur " est-il toujours valable dans les versions les plus récentes de SQL Server?- Si tel est le cas, existe-t-il un bon exemple montrant sa validité dans SQL Server 2008 R2?
Merci beaucoup pour vos réflexions à ce sujet!
MODIFIER
J'ai trouvé la création de procédures stockées (moteur de base de données) sur msdn pour SQL Server 2008 R2, ce qui répond à ma deuxième question:
Nous vous recommandons de ne créer aucune procédure stockée utilisant sp_ comme préfixe. SQL Server utilise le préfixe sp_ pour désigner les procédures stockées du système. Le nom que vous choisissez peut entrer en conflit avec une procédure système future. [...]
Rien n’y est fait mention des problèmes de performances causés par l’utilisation du sp_
préfixe. J'aimerais savoir si c'est toujours le cas ou s'ils l'ont corrigé après SQL Server 2000.
sp_
versions légèrement supérieur (il faut archiver les bases de données maître et utilisateur, car il priorise les processus système dansmaster
-> procs dans la base de données utilisateur -> non système Procs dansmaster
)sp_
? C'est à peu près aussi utile que de préfixer une table avectbl
. Pourquoi faire d'abord de la recherche système (même si la différence de performances est négligeable ou nulle) pour vous permettre d'utiliser cette convention de dénomination sans signification?dbo.sp_Author_Rename
est mieux quedbo.Author_Rename
. Je ne peux pas penser à une seule chose qui a du sens.Réponses:
C'est assez facile de vous tester. Créons deux procédures très simples:
Construisons maintenant un wrapper qui les exécute plusieurs fois, avec et sans le préfixe du schéma:
Résultats:
Conclusions:
La question plus importante: pourquoi voudriez - vous voulez utiliser le préfixe sp_? Qu'est-ce que vos collègues attendent à gagner de le faire? Cela ne devrait pas vous obliger à prouver que c'est pire, mais plutôt à justifier de l'ajout du même préfixe de trois lettres à chaque procédure stockée dans le système. Je ne vois pas le bénéfice.
J'ai également effectué des tests assez poussés sur ce modèle dans l'article suivant du blog:
http://www.sqlperformance.com/2012/10/t-sql-queries/sp_prefix
la source
sp_
afin de pouvoir la différencier des autres éléments et éviter tout conflit de nom ... Je ne savais pas que ce problème de performances existait.Comme le montre le simple commentaire de Martin Smith - oui, si vous avez une procédure stockée avec un
sp_
préfixe - l'exécuteur de la requête SQL Server vérifie toujours dans lamaster
base de données s'il existe une procédure stockée (marquée comme procédure stockée système) portant ce nom.Et si elle existe, cette procédure stockée système de la
master
base de données prévaut toujours et sera exécutée à la place de la vôtre.Alors oui, cela reste: n'utilisez pas le
sp_
préfixe.la source
CREATE PROC dbo.sp_helptext AS SELECT 1
puis essayezEXEC dbo.sp_helptext
master
sp.Un meilleur test consiste à rédiger une requête qui nécessite une optimisation complète, car cela reflète probablement mieux ce que fait le proc que vous écrivez. J'ai enveloppé la requête suivante dans un SP et répété votre test et obtenu les mêmes résultats.
J'ai eu le même nombre d'événements manqués et touchés dans le cache dans les deux cas et dans les deux cas, le plan a été ajouté au cache. J'ai également exécuté les deux procs plusieurs fois et il n'y avait aucune différence cohérente dans le temps CPU ou le temps écoulé signalé par dm_exec_query_stats.
L'autre préoccupation est que, puisque les procédures "sp_" peuvent être exécutées à partir du maître, vous pouvez obtenir une copie du processus exécuté dans maître au lieu de la base de données sur laquelle vous travaillez, mais un test rapide montrera que ce n'est pas le cas. Cependant, si le processus est supprimé de la base de données dans laquelle vous travaillez et qu'une copie existe en maître, il sera exécuté, ce qui pourrait poser problème s'il s'agit d'une ancienne version. Si cela pose problème, je n’utiliserais pas «sp_» pour nommer le proc.
la source
Je pense que le problème doit être résolu lorsque vous ne spécifiez pas le nom d'objet pleinement qualifié. Donc, "EXEC sp_something" vérifie d'abord le maître, mais "EXEC dbname.dbo.sp_something" ne sera jamais traité en premier.
La leçon, si je me souviens bien, est d'utiliser toujours le nom complet.
la source
EXEC MyDB.dbo.sp_helptext 'sp_helptext'
utilise toujours celui de,master
même s’il en existe un dans la base de données des utilisateurs. Autant que je sache, il vérifie les deux emplacements et utilisera celui demaster
s'il existe et est marqué comme objet système.MyDB.dbo.sp_foo
j'exécutais encore la version principale). Je n'ai pas 2008/2008 R2 pour le moment pour confirmer en quoi ce comportement a changé.