Soci (Soczó Zsolt) szakmai blogja

2007.05.03.

Dátum levágása TSQL-ben

Filed under: Adatbázisok,SQL Server,SQL Server 2005,Szakmai élet — Soczó Zsolt @ 22:04

Egyik MSHU-s jóakaróm jóvoltából megkaptam a teljes Inside TSQL 2005 sorozatot, és még jó pár egyéb könyvet is.
Az első részen, a Storage Engine részen már túlvagyok, sok érdekes dolgot olvastam benne, amelyeket majd egyik kevésbé rohanós pillanatomban összeszedek címszavakban.
Csak egyet emelnék ki. 2005-ben NEM a tranzakciós logból állítják elő a triggerek számára az inserted és deleted táblákat, hanem a snapshot isolationhöz kidolgozott row versioning eljárással. Na, ez pl. nekem új volt.

No, amit viszont most szeretnék bemutatni a TSQL Programing c. második kötetből, hogy egy időpontot is tartalmazó dátumról hogyan lehet hatékonyan levágni az idő részt (ha már egyszer nincs rendes date és time típus):

dateadd(d, 0, datediff(d, 0, getdate()))

Ügyes, ezt még nem láttam.

Én ezt ismertem, ez is benne van a könyvben:

cast(convert(varchar(8), getdate(), 112) as datetime)

Ezzel viszont már szívtam, mert itt ugye arra bazírozunk, hogy levágódik az idő rész a varchar hossza miatt, ez viszont egyes esetekben kiborítja a szervert. Asszem indexelt, számított oszlopban akartam ezt használni, de nem engedte, a túlcsordulás miatt. Mellesleg az első verzió szerintem sokkal gyorsabb.

Nem álltam meg, megmértem őket:

[source:SQL]
declare @i int, @e int
set @i = 0
set @e = 1000000

declare @start datetime
declare @end datetime
declare @d datetime

set @start = getdate()
while(@i < @e) begin --set @d = dateadd(d, 0, datediff(d, 0, getdate())) set @d = cast(convert(varchar(8), getdate(), 112) as datetime) set @i = @i + 1 end set @end = getdate() select datediff(ms, @start, @end) [/source] Az első verzió nálam kb. 1300 ms alatt fut le, a második 2000 körül. Nem óriási a különbség, de a stringes megoldás hibás viselkedése miatt most már inkább az elsőt preferálom. Van jobb megoldás esetleg?

5 Comments

  1. Mondjuk én nem értem a varchar(8)-at!
    Miért varchar és miért 8?

    Én ezt használom már 7 éve, és nem volt még gondom vele (igaz, hogy indexelt, számított oszlopban még nem próbáltam):

    select convert(datetime, convert(char(10), getdate(), 102))

    A mérési eredményed alapján gondolom, hogy ez is hasonlóan teljesít, mint amit kidobtál! Vagy lehet, hogy annál egy kicsit jobban, talán a char miatt?

    Megmérnéd?

    Comment by Szőke László — 2007.09.01. @ 16:47

  2. Ne mérd meg vazze, de azért kíváncsi lennék arra amit kérdeztem!

    Comment by Szőke László — 2007.09.08. @ 21:45

  3. Szőke Úr,
    mostanában nem ez volt a legfontosabb, hogy méricskéljek:

    http://soci.hu/blog/index.php/2007/09/09/megjottunk-soczo-panni-kamilla-es-soczo-benedek-gergo/

    Amúgy meg ott a kód, amivel mértem, csak le kell futtatnod.

    Comment by Soczó Zsolt — 2007.09.09. @ 14:40

  4. Tényleg ott a kód, bocs!

    És a két kérdésem?

    Kezdem fordított sorrendbe:
    2.)
    Azt nem értem igazán, hogy miért használt valaki 8-at 10 helyett? Miért 20070910-re konvertál valaki, ha lehet konvertálni 2007.09.10-re is vagy 2007-09-10-re, stb?

    Miért jó stresszelni a szervert azzal, hogy na vazze, találd ki, hogy mire gondoltam!

    A 2007-09-10 azért jobb, mert ha az év van elöl, akkor a 2. a hónap, a 3. meg a nap. Nem tudok olyanról, hogy valahol a világon használnak ilyen sorrendet: ÉÉÉÉ.NN.HH.

    1.)
    Ha fix, hogy fix a hossz, akkor miért jó varchart használni char helyett?

    Tovább tart begépelni, ha már más szempont nem is számít!

    TOVÁBBÁ
    Ha már a teljesítmény ennyire központi téma nálad, akkor miért használsz SET-et lokális változók beállogatására?

    Ha egy helyen csak egyetlen változót kell beállítanod, akkor megértem, mert rövidebb begépelni mint a select-et.

    De! Miért használsz SET-et, ha egy helyen több értékadást is el kell végezned?

    set @a = 1
    set @b = 2

    helyett inkább:

    select @a = 1, @b = 2

    Mérhető a különbség!

    ÉS EGY KIS RÁADÁS:
    Miért jó a kód elején belőni két változót, amit 1 kilométerrel odébb használsz.

    Inkább így:
    select @i = 0, @e = 2000000;
    while (@i

    Comment by Szőke László — 2007.09.10. @ 09:15

  5. Bő lé…

    Inkább így:
    select @i = 0, @e = 2000000;
    while (@i

    Comment by Szőke László — 2007.09.10. @ 09:16

RSS feed for comments on this post.

Sorry, the comment form is closed at this time.

Powered by WordPress