Avatar billede anders_cp Nybegynder
30. september 2009 - 22:57 Der er 5 kommentarer og
1 løsning

Optimering af funktion

Hej
Jeg har en stored procedure som indeholder et view der henter fra et view og igen hen..., ting som gør forespørgslen langsom, men som det vil være for vidt og indvie jer i her. Derimod mistænker jeg en funktion jeg har lavet for at være en medvirkende årsag til at få det til at køre langsomt.

Jeg håber I kan hjælpe mig med at optimere funktionen. Funktionen kommer her med forklarende tekst til:

-- Create date: <7. april 2009>
-- Description:    <Will find the workingdays from activitystart until datetime.now>
-- =============================================


-- DER ØNSKES FØLGENDE RETURNERET
-- (L)5 LUKKET OG HAR VÆRET REPARARET I 5 DAGE
-- 5 VÆRET REPARARET I 5 DAGE, MEN ER STADIG ÅBEN
ALTER FUNCTION [dbo].[WorkingDays]
-- aktivitetsid'et angiver et id på en reparation, der tager x-antal arbejdsdage at reparare.
(
    -- Add the parameters for the function here
    @ActivityID int,
    -- Getdate() - function is not allowed in a function
    @Datenow DATETIME
)


RETURNS VARCHAR(20)
AS
BEGIN
    -- Declare the return variable here
    DECLARE @WorkingDays VARCHAR(20)
    DECLARE @DayFrom DATETIME
    DECLARE @DayTo DATETIME
    DECLARE @OffDays INT
    DECLARE @ActivityClosed  BIT
    DECLARE @Prefix CHAR(4)

    -- Add the T-SQL statements to compute the return value here
-- STARTTIDSPUNKTET FOR REPARATIONEN.
SET @DayFrom = (SELECT Activities.ActivityStartDateTime
                FROM Activities
                WHERE ActivityID = @ActivityID)
               
-- ... UNDERSØGES FOR OM REPARATIONEN ER SLUT 0 = ÅBEN 1 = LUKKET (SLUT)
SET @ActivityClosed =(SELECT Activities.ActivityClosed
                FROM Activities
                WHERE ActivityID = @ActivityID)

-- HVIS DEN IKKE ER LUKKET SKAL DER IKKE VÆRE ET PREFIX
--  OG DATOEN TIL SKAL VÆRE DAGS DATO
IF (@ActivityClosed = 0)
    BEGIN
        SET @DayTo = @Datenow
        SET @Prefix = ''
    END
ELSE
-- HVIS REPARATIONEN ER LUKKET SKAL PRÆFIX VÆRE (L)
-- OG DATOEN TIL SKAL VÆRE LUKKEDATOEN (ACTIVITYENDDATETIEM)
    BEGIN
        SET @DayTo = (SELECT Activities.ActivityEndDateTime
                FROM Activities
                WHERE ActivityID = @ActivityID)
        SET @Prefix = '(L) '
--        SET @Prefix = ''
    END


SELECT    @OffDays = COUNT(DateID)
FROM    Calender
-- JEG HAR LAVET EN KALENDER -TABEL DER SER SÅDAN UD
--
--1998-01-01 00:00:00.000    1    Nytårsdag
--1998-01-02 00:00:00.000    0    NULL
--1998-01-03 00:00:00.000    1    NULL
--1998-01-04 00:00:00.000    1    NULL
--1998-01-05 00:00:00.000    0    NULL

WHERE    (DayOff = 1) AND (DateID > @DayFrom) AND (DateID <= @DayTo)
SET    @WorkingDays = DATEDIFF( day , @DayFrom, @DayTo) -  @OffDays
   
RETURN (@Prefix + @WorkingDays)

END

-- Måske vil det hjælpe at Præfix? - det er blot en smart feature jeg har lavet - men folk vil godt nok blive kede af det :-(
Avatar billede teepee Nybegynder
01. oktober 2009 - 08:30 #1
Du selecter for det første fra den samme linie tre gange. Dette kan skrives som én linie. Min T-SQL er ikke den skarpeste, men en case kan vel gøre at du sætter @DayTo til @Datenow hvis @ActivityClosed = 0 og ellers ActivityEndDateTime, i samme sql selecter du dine andre variable. Hvis dit view ér langsomt så skulle det gerne gå hurtigere kun at selecte én gang.

Ellers, hvordan ser viewet ud. Nogle grimme joins? Måske at der mangler statistikker?
Avatar billede anders_cp Nybegynder
02. oktober 2009 - 11:14 #2
Ja der er masser af joints. Hvad mener du med "mangler i statistikker"?
Avatar billede anders_cp Nybegynder
02. oktober 2009 - 12:06 #3
Jeg er med på hvad du mener med at jeg selecter tre gange, men jeg ved ikke hvordan jeg skal få løst problemet med en CASE. Har prøvet følgende:

SELECT
    Activities.ActivityStartDateTime
    , Activities.ActivityClosed
   
CASE
WHEN Activities.ActivityClosed = 0 THEN
    BEGIN
        SET @DayTo = @Datenow
        SET @Prefix = ''
    END
ELSE
    BEGIN
        SET @DayTo = (SELECT Activities.ActivityEndDateTime
                FROM Activities
                WHERE ActivityID = @ActivityID)
        SET @Prefix = '(L) '
--        SET @Prefix = ''
    END

   
FROM Activities
WHERE ActivityID = @ActivityID


Som giver fejlmedd:
Msg 156, Level 15, State 1, Procedure WorkingDays, Line 39
Incorrect syntax near the keyword 'CASE'.
Msg 156, Level 15, State 1, Procedure WorkingDays, Line 45
Incorrect syntax near the keyword 'ELSE'.
Msg 156, Level 15, State 1, Procedure WorkingDays, Line 58
Incorrect syntax near the keyword 'FROM'.
Avatar billede teepee Nybegynder
02. oktober 2009 - 13:53 #4
du skal selecte en kolonne ud, altså værdien som du ønsker at sætte ind i DayTo, du skal ikke bruge sæt inde i selecten/casen
Avatar billede Syska Mester
03. oktober 2009 - 15:33 #5
Avatar billede anders_cp Nybegynder
21. oktober 2009 - 21:41 #6
Jeg synes ikke jeg har fået den helt store performance forbedring. Jeg har læst lidt om Cache, som jeg vil forsøge mig lidt med.

Tillader mig at lukke denne tråd. Tak for alle svarene ;)
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Computerworld tilbyder specialiserede kurser i database-management

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester