MS SQL Server posiada zbiór predefiniowanych systemowych procedur składowanych zapisanych w bazie master, których nazwy zaczynają się od prefiksu 'sp_’. Użytkownik może również stworzyć swoją procedurę w bazie master o prefiksie 'sp_’. Co za tym się kryje? Poniżej przedstawiam kilka zebranych uwag na ten temat.

MS SQL Server posiada zbiór predefiniowanych procedur składowanych, które zapisane są w:

  • bazie master – nazwy tych procedur rozpoczynają się od prefiksu sp_.
    Służą one do pobierania i konfigurowania opcji serwera i baz danych.
  • jako pliki bibliotek dynamicznych dll  – nazwy tych procedur rozpoczynają się od prefiksu xp_.

Istnieje również możliwość tworzenia:

  • własnych procedur składowanych, które przechowywane są w bazie użytkownika,
  • tymczasowych procedur składowanych, które charakteryzują się tym, że nazwy tych procedur rozpoczynają się pojedynczym lub podwójnym znakiem #.

MS SQL Server zapisuje ciało procedury składowanej w tabeli systemowej syscomments, a nazwę w tabeli sysobjects.

W trakcie pierwszego uruchomieniu procedury optymalizator SQL Server przygotowuje i kompiluje plan wykonania. Plan ten przechowywany jest w buforze procedury (Procedure cache) skąd jest pobierany przy ponownym uruchomieniu procedury.

W tym momencie chcę przedstawić kilka spostrzeżeń:

Po pierwsze:

Wiele osób wzorując się na konwencji nazewniczej stosowanej dla procedur systemowych tworzy własne procedury składowane używając prefiksu ’sp_’.  Jest to błędne postępowanie ponieważ ze względu na wydajność nie należy postępować w ten sposób, no chyba że procedury składowane użytkownika zostaną zapisane w bazie master.

Dla przykładu:

  • należy stworzyć dwie proste procedury w bazie użytkownika czy też w bazie tempdb i nazwać je odpowiednio: dbo.foo i dbo.sp_foo
  • następnie należy wywołać utworzone procedury w celu skompilowania planu wykonania.
  • kolejny krok to uruchomienie Profilera i stworzenie w nim zdarzenia klasy  Stored Procedur Cache Miss
  • następnie należy ponownie wywołać dwie utworzone wcześniej procedury tj. dbo.foo i dbo.sp_foo.

W przypadku uruchomienia procedury dbo.foo Profiler nie zanotował żadnego zdarzenia, a w przypadku uruchomienia procedury dbo.sp_foo w Profilerze widać zdarzenie SP:CacheMiss. Oznacza to, że SQL Server domyślnie szuka planu wykonania dla procedur o prefiksie sp_ w buforze bazy master. Nie znajdując go tam skompilował ponownie procedurę sp_foo.

W przypadku odwoływania się do procedury za pomocą jej pełnej nazwy, opisany powyżej problem nie wystąpi.

Po drugie:

  • Zaleca się aby nie tworzyć żadnych procedur z prefiksem sp_. SQL Server używa prefiksu sp_ do oznaczenia systemowych procedur składowanych.
  • Może zdarzyć się, że w kolejnych wersjach MS SQL Server może nastąpić konflikt nazw tzn. mogą pojawić się systemowe procedury składowane o tej samej nazwie.
  • Jeśli aplikacja wywołuje procedurę poprzez samą jej nazwę lub jest w schemacie dbo nie korzystając z wyspecyfikowanych nazw schemy to wywoła się systemowa procedura składowana, a nie procedura użytkownika.

Po trzecie:

Używanie prefiksu sp_ jest wątpliwą praktyką, ponieważ stwarza możliwość posiadania dwóch różnych wersji tej samej procedury i można przez pomyłkę wywołać tą złą.

Po czwarte:

Systemowa procedura składowana tak naprawdę jest specjalnie oznakowana w tabelach systemowych, a prefiks to jedynie nazewnictwo. Samo dodanie prefiksu do nowo utworzonej procedury nie sprawi, że będzie ona procedurą systemową.

Po piąte:

Nie mniej jednak przestrzegając pewnych zasad można tworzyć nie tylko procedury składowane ale również tabele i widoki w bazie master z prefiksem sp_ . Obiekty te są wtedy dostępne z poziomu dowolnej bazy danych użytkownika.

W ten sposób tworzy się procedury, które służą nam jako własne narzędzia.

Linki:


Dariusz Brejnak

Od prawie trzydziestu lat jest pasjonatem informatyki, a zwłaszcza dziedzin dotyczących baz danych, hurtowni danych oraz ogólnie rozumianej tematyki BI. Jego druga pasja to fotografia http://dariuszbrejnak.pl