BETA
Aby się zalogować, najpiew wybierz portal.
Aby się zarejestrować, najpiew wybierz portal.
Podaj słowa kluczowe
Słowa kluczowe muszą mieć co najmniej 3 sąsiadujące znaki alfanumeryczne
Pole zawiera niedozwolone znaki
Michał  Gołoś
Michał Gołoś
38 pkt.
Poczatkujacy

 
0


Witam,

niedawno przeczytałem wątek:
http://www.wss.pl/frmThread.aspx?tid=72132

w którym Marek opisał problemy z wykorzystanie SELECT INTO.
Wiele osób się z tym zgadza, ale ...
nie wszyscy.
Druga strona medalu wygląda tak że problem z blokowaniem został rzekomo naprawiony już w wersji 7.0
http://support.microsoft.com/kb/162361
http://support.microsoft.com/kb/153441/EN-US/

a do tego (przytoczę wypowiedź kolegi):

"SELECT INTO ma przewagę nad INSERT INTO taką że ta pierwsza jest nie logowana w trybie recovery SIMPLE i BULK-LOGGED, a tabele tymczasowe są w na bazie tempdb gdzie zawsze jest tryb SIMPLE."

Proszę powiedźcie jaka jest prawda ?
Jeżeli problem nadal występuje to jak go powtórzyć (próbowałem na wiele sposobów) ?





Paweł Potasiński Microsoft
Paweł Potasiński
7713 pkt.
Guru
 
0


Blokowanie nadal jest problemem. Prosty test:

-- sesja nr 1
begin tran
select *
into newtable
from sys.databases

-- sesja nr 2
SELECT
l.request_session_id AS SPID,
DB_NAME(l.resource_database_id) AS DatabaseName,
o.name AS LockedObjectName,
p.object_id AS LockedObjectId,
l.resource_type AS LockedResource,
l.request_mode AS LockType
FROM sys.dm_tran_locks l
JOIN sys.partitions p WITH (NOLOCK)
ON p.hobt_id = l.resource_associated_entity_id
JOIN sys.objects o WITH (NOLOCK)
ON o.object_id = p.object_id
WHERE l.resource_database_id = db_id()
AND l.request_session_id = 56 -- tu zmień na spid sesji nr 1

Wynik:
- lock Sch-M na obiekcie newtable,
- locki X i IX na obiektach systemowych

A co do tego nie logowania operacji SELECT INTO, to jak kolega, którego zdanie przytoczyłeś, wyjaśni, że wykonanie ROLLBACK na sesji nr 1 wycofa utworzenie tabeli newtable? :-) Są logowane - jest takie określenie "minimally logged" w BOL.

Z tym trybem SIMPLE dla tempdb to też chyba nie do końca tak. O ile wiem tempdb ma swój własny, nieco inny recovery model. Ale tu już nie jestem kompetentny, żeby się wypowiadać. Taką wiedzę ma np. Maciek Pilecki.

--
Pozdrawiam
Paweł Potasiński

[ PLSSUG.org.pl ] | [ SQLGeek.pl ] | [ VirtualStudy.pl ]

Edytowano 1 raz. Ostatnio 2010-01-05 20:15:30 przez C3PO.

Pozdrawiam,
Paweł Potasiński

Maciej Pilecki
Maciej Pilecki
131 pkt.
Junior
 
1


No to skoro zostałem wywołany do tablicy to proszę:

Od czasów 6.5 SP1 (z trace flagą) oraz 7.0 (bez flagi) SELECT INTO jest realizowane jako dwie osobne transakcje - jedna zakłada tabelę, druga zapełnia ją danymi. W ten sposób omija się problem trzymania locków na tabelach systemowych. Jest to zresztą opisane w przytoczonym w pierwszym poście KB153441 (przedostatni akapit) - włącznie z faktem, że przedstawiony przez Pawła przykład jest przypadkiem szczególnym bo opakowując SELECT INTO w transakcję użytkownika prosimy o realizację całości w pojedynczej transakcji (czyli z trzymaniem locków również na obiektach systemowych).

Do zilustrowania tego wystarczy bardzo prosty przykład gdzie mamy run-time error w drugiej transakcji, która realizuje fazę SELECT:
USE AdventureWorks

SELECT POWER(TotalDue, 10) AS X
INTO newtable
FROM Sales.SalesOrderHeader

select * from newtable
I tutaj okazuje się bardzo prosto, że pomimo że nasz SELECT INTO się "wykrzaczył", to tabela jednak powstała i nie zostało to wycofane. Dlaczego? Ano dlatego, że odbyło się to w osobnej transakcji. Ładnie też to widać w Profilerze (zdarzenia SQLTransaction).

Co do logowania natomiast to proponuję zacząć od ustalenia co to jest "minimalne logowanie" (bo czegoś takiego jak "operacja nielogowana" w bazie oczywiście nie ma - może być tylko "minimalnie logowana", chociaż sam MS się w tej sprawie czasem myli). Otóż "minimalnie logowana" opracja to taka, gdzie logowane są tylko informacje potrzebne do wycofania (roll-back) ale już nie do powtórzenia (roll-forward) transakcji. Co za tym idzie, logowanie minimalne wymaga znacznie mniej miejsca w logu i poprawia wydajność. Oczywiście nadaje się to tylko do niektórych operacji, które mają jasno zdefiniowany zakres i nie odbywają się przy jednoczesnym dostępie do obiektów, których dotyczą - najczęstszymi przykładami jest SELECT INTO, INSERT do pustej tabel albo tabeli bez indeksów (pod paroma warunkami) oraz CREATE INDEX. Oczywiście minimalne logowane działa tylko w trybach SIMPLE i BULK-LOGGED (stąd nazwa tego trybu zresztą), a i to nie zawsze.
I jeśli tutaj mamy jasność, to teraz o tempdb. Wszyscy wiemy, że tempdb jest w zawsze trybie SIMPLE, co jest natomiast mniej znane, to fakt że jest to dość "szczególny" tryb, odmienny niż w pozostałych bazach. Nieco upraszczając różnica polega na tym, że w tempdb każda operacja traktowana jest minimalnie logowana - rownież operacje, które w innych bazach są logowane w pełni. Wynika to z prostego faktu, że jedyna operacja jaka nas interesuje w tempdb to roll-back transakcji, natomiast roll-forward nigdy nie będzie miał miejsca (ponieważ na tempdb nie jest przeprowadzane recovery).

Mam nadzieję, że to wyjaśnia wątpliwości... Pozdrawiam,
Maciej Pilecki
MCT, MCDBA, MCSD, MCSE
SQL Server MVP

Pozdrawiam,
Maciej Pilecki
MCT, MCDBA, MCSD, MCSE
SQL Server MVP, MCM

Paweł Potasiński Microsoft
Paweł Potasiński
7713 pkt.
Guru
 
0


Wiedziałem, co robię, wywołując Cię do tablicy :-) Dzięki. --
Pozdrawiam
Paweł Potasiński

[ PLSSUG.org.pl ] | [ SQLGeek.pl ] | [ VirtualStudy.pl ]

Pozdrawiam,
Paweł Potasiński

Michał  Gołoś
Michał Gołoś
38 pkt.
Poczatkujacy
 
0


No dobrze, ale blokowanie będzie też przy jawnym tworzeniu tabeli.
Logowanie w tempdb jest takie samo dla obu przypadków.
W takim razie, dlaczego mówi się, że nie powinno się stosować SELECT INTO poza oczywiście dobrą praktyką (jawna deklaracja) ?
Czy jest jakiś powód żeby nie stosować SELECT INTO, bo trochę zwątpiłem :|

Maciej Pilecki
Maciej Pilecki
131 pkt.
Junior
 
0


Ja osobiście uważam że nie ma powodów aby nie stosować SELECT INTO.
Z powodami wymienionymi przez Marka w cytowanym wątku nie zgadzam się, co już chyba udowodniłem powyżej. Mogę się jedynie zgodzić z uwagami dotyczącymi problemów z kontrolą nad schematem powstającej tabeli - ale na to też są sposoby, trzeba tylko mieć to na uwadze.

Wydaje mi się, że niechęć wielu osób do SELECT INTO wynika z różnych zaszłości historycznych, co mój znajomy Tony Davis ładnie opisał tutaj. Pozdrawiam,
Maciej Pilecki
MCT, MCDBA, MCSD, MCSE
SQL Server MVP

Pozdrawiam,
Maciej Pilecki
MCT, MCDBA, MCSD, MCSE
SQL Server MVP, MCM

Marek Adamczuk Ekspert WSS
Marek Adamczuk
2392 pkt.
Guru
 
0


Select into jest rzeczywiście dwiema transakcjami - moje przekonania istotnie opierałem na doświadczeniach ze starych wersji i oczywiście były one błędne. Posypuję głowę popiołem. A swoją drogą wstręt mi pozostał. Konstrukcja SELECT INTO łamie zasadę mówiącą, że pojedyncze polecenie modyfikujące jest niejawną transakcją. Nawet przypominam mi się przypadek, kiedy takie długie select .. into #t przerwałem, a przy ponownej próbie dowiedziałem się, że tabela istnieje - wtedy uznałem to za błąd, dziś wiem, że to by design. Dziś przećwiczyłem to ponownie i efekt jest powtarzalny.

Dzięki za czujność i dążenie do prawdy.
Podziękowania również dla Maćka za obszerne wyjaśnienia.

__________
Pozdrawiam
Marek Adamczuk
Blog

__________
Pozdrawiam
Marek Adamczuk

Maciej Pilecki
Maciej Pilecki
131 pkt.
Junior
 
0


Pawle, przy okazji proponuję małą modyfikację to Twojego zapytania o locki:
SELECT
l.request_session_id AS SPID,
DB_NAME(l.resource_database_id) AS DatabaseName,
o.name AS LockedObjectName,
COALESCE(p.object_id, o.object_id) AS LockedObjectId,
l.resource_type AS LockedResource,
l.request_mode AS LockType
FROM sys.dm_tran_locks l
LEFT JOIN sys.partitions p WITH (NOLOCK)
ON p.hobt_id = l.resource_associated_entity_id
LEFT JOIN sys.objects o WITH (NOLOCK)
ON o.object_id = p.object_id OR o.object_id = l.resource_associated_entity_id
WHERE l.resource_database_id = db_id()
AND l.request_session_id = 56
Lepiej działa kiedy lock jest na poziomie tabeli... Pozdrawiam,
Maciej Pilecki
MCT, MCDBA, MCSD, MCSE
SQL Server MVP

Pozdrawiam,
Maciej Pilecki
MCT, MCDBA, MCSD, MCSE
SQL Server MVP, MCM

Udziel odpowiedzi

pkt.
Treść wpisu:

Zaloguj się lub Zarejestruj się aby wykonać tę czynność.