Einer meiner Mitarbeiter hat eine gespeicherte Prozedur in unserer SQL Server 2008 R2-Datenbank benannt sp_something
. Als ich das sah, dachte ich sofort: "Das ist FALSCH!" und fing an, in meinen Lesezeichen nach diesem Online-Artikel zu suchen , der erklärt, warum er falsch ist, damit ich meinem Kollegen eine Erklärung geben konnte.
In dem Artikel (von Brian Moran ) wird erläutert, dass SQL Server die Master-Datenbank nach einem kompilierten Plan durchsucht , wenn der gespeicherten Prozedur ein sp_- Präfix zugewiesen wird. Da sich der sp_sproc
nicht dort befindet, kompiliert SQL Server die Prozedur neu (und benötigt dafür eine exklusive Kompilierungssperre, die zu Leistungsproblemen führt).
Das folgende Beispiel wird in dem Artikel angegeben, um den Unterschied zwischen zwei Prozeduren zu zeigen:
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
Sie führen dies aus, öffnen dann den Profiler (fügen Sie das SP:CacheMiss
Ereignis Gespeicherte Prozeduren -> hinzu ) und führen die gespeicherten Prozeduren erneut aus. Sie sollten einen Unterschied zwischen den beiden gespeicherten Prozeduren feststellen: Die sp_Select1
gespeicherte Prozedur generiert ein SP:CacheMiss
Ereignis mehr als die Select1
gespeicherte Prozedur (der Artikel verweist auf SQL Server 7.0 und SQL Server 2000 ).
Wenn ich das Beispiel in meiner SQL Server 2008 R2-Umgebung ausführe, erhalte ich SP:CacheMiss
für beide Prozeduren die gleiche Anzahl von Ereignissen (sowohl in tempdb als auch in einer anderen Testdatenbank).
Ich frage mich also:
- Kann ich bei der Ausführung des Beispiels etwas falsch gemacht haben?
Ist dassproc sp_something
Adagium " Benutzer nicht benennen " in neueren Versionen von SQL Server noch gültig?- Wenn ja, gibt es ein gutes Beispiel für die Gültigkeit in SQL Server 2008 R2?
Vielen Dank für Ihre Gedanken dazu!
BEARBEITEN
Ich fand Stored Procedures (Database Engine) Erstellen von auf Msdn für SQL Server 2008 R2, die meine zweite Frage beantwortet:
Es wird empfohlen, keine gespeicherten Prozeduren mit sp_ als Präfix zu erstellen. SQL Server verwendet das Präfix sp_, um gespeicherte Systemprozeduren anzugeben. Der von Ihnen gewählte Name kann zu Konflikten mit zukünftigen Systemprozeduren führen. [...]
Über Leistungsprobleme, die durch die Verwendung des sp_
Präfixes verursacht werden, wird dort jedoch nichts erwähnt . Ich würde gerne wissen, ob dies immer noch der Fall ist oder ob es nach SQL Server 2000 behoben wurde.
sp_
Versionen zurückzuführen ist (muss sowohl in der Master- als auch in der Benutzerdatenbank eingecheckt werden, da System-Procs inmaster
-> Procs in der Benutzer-DB -> non system Vorrang haben) procs inmaster
)sp_
? Dies ist ungefähr so nützlich wie das Präfixieren einer Tabelle mittbl
. Warum sollte der Systemsuchmaster zuerst eingerichtet werden (auch wenn es sich um einen vernachlässigbaren oder keinen Leistungsunterschied handelt), damit Sie diese bedeutungslose Namenskonvention verwenden können?dbo.sp_Author_Rename
das besser ist alsdbo.Author_Rename
. Mir fällt nichts ein, was Sinn macht.Antworten:
Dies ist ziemlich einfach, sich selbst zu testen. Lassen Sie uns zwei sehr einfache Prozeduren erstellen:
Erstellen wir nun einen Wrapper, der sie mehrmals mit und ohne das Schema-Präfix ausführt:
Ergebnisse:
Schlussfolgerungen:
Die wichtigere Frage: Warum würden Sie wollen den sp_ Präfix benutzen? Was Ihre Mitarbeiter erwarten zu gewinnen , so zu tun? Es sollte nicht darum gehen, dass Sie beweisen müssen, dass dies schlimmer ist, sondern darum, dass Sie jedem einzelnen gespeicherten Vorgang im System dasselbe Präfix aus drei Buchstaben hinzufügen. Ich sehe den Nutzen nicht.
Außerdem habe ich dieses Muster in folgendem Blog-Beitrag ausführlich getestet:
http://www.sqlperformance.com/2012/10/t-sql-queries/sp_prefix
quelle
sp_
damit sie von anderen Dingen unterschieden werden konnte und keine Namenskonflikte auftraten. Ich hatte keine Ahnung, dass dieses Leistungsproblem damit bestand.Wie Martin Smiths einfacher Kommentar zeigt - Ja, wenn Sie eine gespeicherte Prozedur mit einem
sp_
Präfix haben -, überprüft der SQL Server-Abfrage-Executor immermaster
zuerst die Datenbank, um festzustellen, ob eine gespeicherte Prozedur (die als gespeicherte Systemprozedur gekennzeichnet ist) mit diesem Namen vorhanden ist.Und wenn es existiert, hat diese gespeicherte Systemprozedur aus der
master
Datenbank immer Vorrang und wird anstelle Ihrer eigenen ausgeführt.Also ja - es steht immer noch: Verwenden Sie nicht das
sp_
Präfix.quelle
CREATE PROC dbo.sp_helptext AS SELECT 1
dann versuchenEXEC dbo.sp_helptext
master
SPs.Ein besserer Test besteht darin, eine Abfrage zu schreiben, die eine vollständige Optimierung erfordert, da dies wahrscheinlich eine bessere Reflektion dessen ist, was der von Ihnen geschriebene Prozess tut. Ich habe die folgende Abfrage in einen SP eingeschlossen, Ihren Test wiederholt und die gleichen Ergebnisse erhalten.
Ich habe in beiden Fällen die gleiche Anzahl an Cache-Miss- und -Hit-Ereignissen erhalten, und in beiden Fällen wurde der Plan dem Cache hinzugefügt. Ich habe auch beide Prozesse mehrmals ausgeführt und es gab keinen konsistenten Unterschied in der CPU-Zeit oder der verstrichenen Zeit, der von dm_exec_query_stats gemeldet wurde.
Die andere Sorge ist, dass, da "sp_" -Prozesse vom Master ausgeführt werden können, Sie möglicherweise eine Kopie des Prozesses erhalten, der in den Master anstelle der Datenbank, in der Sie arbeiten, ausgeführt wurde, aber ein schneller Test wird zeigen, dass dies nicht der Fall ist. Wenn der Prozess jedoch aus der Datenbank gelöscht wird, in der Sie arbeiten, und eine Kopie im Master vorhanden ist, wird er ausgeführt, was ein Problem sein kann, wenn es sich um eine alte Version handelt. Wenn dies ein Problem ist, würde ich nicht "sp_" verwenden, um den Proc zu benennen.
quelle
Ich glaube, dass das Problem zu tun hat, wenn Sie den vollständig qualifizierten Objektnamen nicht angeben. "EXEC sp_something" prüft also zuerst den Master, "EXEC dbname.dbo.sp_something" geht jedoch niemals zuerst an den Master.
Wenn ich mich recht erinnere, besteht die Lektion darin, immer den vollständig qualifizierten Namen zu verwenden.
quelle
EXEC MyDB.dbo.sp_helptext 'sp_helptext'
verwendet immer noch die von,master
auch wenn es eine in der Benutzerdatenbank gibt. AFAIK überprüft beide Standorte und verwendet den Standort, von demmaster
er existiert und als Systemobjekt markiert ist.MyDB.dbo.sp_foo
noch ausgeführt). Ich habe 2008/2008 R2 derzeit nicht, um zu bestätigen, wo sich dieses Verhalten geändert hat.