2009-05-13 15 views
26

Zastanawiam się nad tabelami tymczasowymi w sp i jak wszystko to może wpłynąć na współbieżność. SP wykonane na serwerze MSSQL 08.Tymczasowe tabele w procedurach przechowywanych

Jeśli mam SP gdzie utworzyć tabelę temp i upuść go ponownie tak:

BEGIN 

CREATE TABLE #MyTempTable 
(
    someField int, 
    someFieldMore nvarchar(50) 
) 

... Use of temp table here 
... And then.. 

DROP TABLE #MyTempTable 

END 

Ten SP będzie nazywany bardzo często, więc moje pytanie jest może nie zawsze występują problemy współbieżności tutaj?

Odpowiedz

28

Nie. Niezależne instancje tabeli tymczasowej będą tworzone dla każdego połączenia.

+0

Dobrze, że jest również to, co myślałem .. Mam nerwowy ponieważ używałem Query Analyzer i zbudować temp tabeli i był w stanie nazwać znowu później, kiedy go nie upuściłem. Ale w świetle twojego postu próbowałem otworzyć nowe zapytanie i próbowałem wywoływać je stamtąd bez powodzenia, a teraz jestem znowu spokojny :) –

+0

Ale pod względem wydajności są poważne problemy z współbieżnością. – tpower

+1

@tpower: Moje rozumienie OP dotyczyło głównie modyfikowania stanu współdzielonego i wątków. Jest oczywiste, że wpłynie to na wydajność. –

17

Może.

Tabele tymczasowe poprzedzone jednym # (#przykład) są przechowywane dla każdej sesji. Jeśli więc twój kod wywoła procedurę przechowywaną ponownie podczas wykonywania innego połączenia (na przykład wątków tła), wywołanie nie powiedzie się, ponieważ już istnieje.

Jeśli jesteś naprawdę martwi użyć zmiennej tabeli zamiast

DECLARE @MyTempTable TABLE 
(
    someField int, 
    someFieldMore nvarchar(50) 
) 

To będzie specyficzny dla „przykład” tego przechowywanego wywołania procedury.

+2

Nie można ponownie użyć sesji SQL, bez względu na to, co klient próbuje zrobić. – gbn

+0

"(#przykład) są przechowywane dla każdej sesji" A sesje są oparte na połączeniu? –

+0

Okay dzięki za to rozliczenie gbn –

7

Niezupełnie i mówię o SQL Server. Tabela tymczasowa (z pojedynczym numerem) istnieje i jest widoczna w zakresie, w którym jest tworzona (związana z zakresem). Za każdym razem, gdy wywołujesz procedurę przechowywaną, tworzy on nowy zakres i dlatego ta tabela tymczasowa istnieje tylko w tym zakresie. Uważam, że tabele tymczasowe są również widoczne dla procedur przechowywanych i udfs, które są również wywoływane w tym zakresie. Jeśli jednak użyjesz podwójnego funta (#), wówczas staną się globalne w twojej sesji i dlatego będą widoczne dla innych procesów wykonawczych w ramach sesji, w której tworzony jest stół tymczasowy i będziesz musiał pomyśleć, czy dostęp do tabeli tymczasowej jest możliwy jednocześnie jest pożądane lub nie.

-1

Baza danych używa tej samej blokady dla wszystkich tabel #temp, więc jeśli używasz dużo, pojawią się problemy z zakleszczeniem. Lepiej używać zmiennych tabel @ dla współbieżności.

+1

-1 Blokada nie jest prawdą, ponieważ SQL Server 6.5 –

-1

Używaj tabel @temp, gdy tylko jest to możliwe - to znaczy, że potrzebujesz tylko jednego klucza podstawowego i nie potrzebujesz dostępu do danych z podrzędnego zapisanego procesu.

Użyj tabel #temp, jeśli potrzebujesz dostępu do danych z podrzędnego zapisanego procesu (jest to zła zmienna globalna do przechowywanego łańcucha wywołań proc) i nie masz innego łatwego sposobu przekazywania danych między przechowywanymi procami. Użyj go również, jeśli potrzebujesz dodatkowego indeksu (chociaż, zadajesz sobie pytanie, czy jest to tabela #temp, jeśli potrzebujesz więcej niż jednego indeksu)

Jeśli to zrobisz, zawsze zadeklaruj swój stół #temp na górze funkcji. SQL wymusi ponowną kompilację twojego zapisanego proca, gdy zobaczy instrukcję create table .... więc jeśli masz deklarację #temp w środku zapisanego proc, zapisany proc musi przestać przetwarzać i rekompilować.

+1

-1 Nie, tymczasowe obiekty (tabele i zmienne) są ogólnie buforowane w SQL Server 2005 i późniejszych, więc unika się rekompilacji. Zobacz http://sqlblog.com/blogs/paul_white/archive/2012/08/17/temporary-object-caching-explained.aspx i http://technet.microsoft.com/en-us/library/cc966545.aspx na przykład –

0

Według SQL Server 2008 Książki Można tworzyć lokalne i globalne tabele tymczasowe. Lokalne tabele tymczasowe są widoczne tylko w bieżącej sesji, a globalne tabele tymczasowe są widoczne dla wszystkich sesji.

„#table_temporal

” ## table_global

Jeśli lokalny tabeli tymczasowej jest tworzony w procedurze przechowywanej lub aplikacji, które mogą być wykonane w tym samym czasie przez kilku użytkowników, Database Engine musi być w stanie odróżnić tabele utworzone przez różnych użytkowników. Aparat baz danych robi to, wewnętrznie dołączając sufiks numeryczny do każdej lokalnej nazwy tabeli tymczasowej.

Potem nie ma problemu.

2

Dla wszystkich osób, które zalecają stosowanie zmiennych tabeli, należy zachować ostrożność. Zmienna tabeli nie może być indeksowana, podczas gdy tabela tymczasowa może być. Zmienna tabelowa jest najlepsza w przypadku pracy z niewielkimi ilościami danych, ale jeśli pracujesz na większych zestawach danych (na przykład zapisach 50 kB), tabela tymczasowa będzie znacznie szybsza niż zmienna tabeli.

Należy również pamiętać, że nie można polegać na próbie/haczyku w celu wymuszenia czyszczenia w ramach procedury składowanej. niektóre typy niepowodzeń nie mogą zostać przechwycone podczas próby/przechwytywania (np. kompilacja błędów z powodu opóźnionego rozpoznawania nazw), jeśli chcesz być naprawdę pewny, że możesz potrzebować utworzyć przechwyconą procedurę przechowywaną, która może wykonać próbę/przechwycić procedurę składowaną procesu roboczego i czyść tam porządek.

np. stworzyć pracownikowi proc AS BEGIN - zrobić coś tutaj END

create proc wrapper AS 
BEGIN 
    Create table #... 
    BEGIN TRY 
     exec worker 
     exec worker2 -- using same temp table 
     -- etc 
    END TRY 
    END CATCH 
     -- handle transaction cleanup here 
     drop table #... 
    END CATCH 
END 
Powiązane problemy