using query optimiser option hints in UDF (User Defined Function)

  • Hi guys.

    Using SQL2000.......

    I have a UDF that takes a single parameter (integer) returns a scalar value (integer).

    The function has four blocks of code. Each one tries to find the value in a different way and only gets executed if the previous block fails to find anything.

    One of the queries is taking about 20 seconds with no options specified. If I use OPTION (MAXDOP 1) the time drops to about 12 seconds. If I use OPTION (foce order) then it is instantaneous.

    When I try to save the UDF I get error messages about incorrect syntax against the OPTION line.

    why can't I use optimiser hints in the query

    sample code is below of the first two SELECT blocks.

    BEGIN

    DECLARE @referralID AS INT

    SET @referralID = 0

    -- get the ID from the linked referral it is exists

    SET @referralID = (SELECT referral_ID FROM contact WHERE contact_ID = @contactID)

    --select @referralID

    IF (@referralID = -1 or @referralID is null )

    BEGIN

    -- get the last referral to the team

    SET @referralID = (SELECT TOP 1

    R.Referral_ID

    FROM

    contact C

    join

    patient_main PM1 on PM1.patient_ID = C.patient_ID AND PM1.z_pr__language_userdesc is null

    left join

    patient_main PM2 on PM2.nhs_number = PM1.nhs_number

    and PM2.patient_ID <> PM1.patient_ID

    and PM2.z_pr__language_userdesc is null

    join

    referral R on R.patient_ID in (PM1.Patient_ID,PM2.Patient_ID)

    and R.staff_date < C.staff_date

    and R.staff_team = c.staff_Team

    WHERE

    C.contact_ID = 16811563--@contactID

    ORDER BY

    R.staff_date DESC

    -- Put OPTION (Force Order) in here --

    )

    END

    ...

    END

    return @referralID

    END

  • update...

    I have rewritten the UDF to be an in-line table function that always returns one column and one row.

    In SQL2000 you cannot pass a row dependent value to a table function (i.e. this won't work)

    select T1.ID, udf_tablefunction(T1.ID) from table1 T1

    NOTE: you can do this in SQL2005.

    so... I copied the UDF to the 2005 server and called all the tables across the servers. Each row takes 5 seconds to return - too slow.....

    Finally I resorted to CURSORS and built a cursor for the records that need updating then call the UDF for each record. This is processing about 15 records per second but I currently have 60K records to update and this is only going to grow (Current time estimate is 70 minutes)

    Any other bright ideas????

  • I don't understand why you're even using a UDF for this update. It looks like you should just be able to join your tables directly to perform the updates.

    Drew

    J. Drew Allen
    Business Intelligence Analyst
    Philadelphia, PA

  • I have now rewritten it directly in the query. The reason for a UDF is it is general functionality and a UDF is the easiest way to achive code reuse. Its kind of messy to have to coalesce four co-related sub queries each time I need to do the calculation.

    I H8 SQL2000. I spent all day on this problem when I could have fixed it in under an hour on SQL2005.

  • Have you considered using a view? That's also a way to reuse code, but it's still set-based.

    Drew

    J. Drew Allen
    Business Intelligence Analyst
    Philadelphia, PA

Viewing 5 posts - 1 through 4 (of 4 total)

You must be logged in to reply to this topic. Login to reply