SQL CLR Data Types and Performance

  • Cool, glad it worked well for you. Another optimization you might try is using the t-sql "returns null on null input" option, which allows sql server to short-circuit null handling without needing to even start running your clr code (you could then get rid of the explicit .IsNull checks in the clr code).

    The diff between decimal and double is that double is a binary approximation of your values (based on ieee 854 std I believe), so you lose some scale accuracy. Decimal is an exact representation of your decimal values, related to the old binary coded decimal system. The important thing is that all the Math lib functions you're using deal in double data type, and those implicit conversions cost you. For a spatial data app I'd expect double to be "close enough" in most cases. If you need more accuracy than the double data type provides you'll probably need to use a different math library.

    Mike C

  • mzak (7/21/2010)


    Hi Jeff. Here's the requested t-sql implementation.

    SET ANSI_NULLS OFF

    GO

    SET QUOTED_IDENTIFIER OFF

    GO

    CREATE Function [dbo].[Distance] (

    @Lat1 as decimal(18, 6),

    @Long1 as decimal(18, 6),

    @Lat2 as decimal(18, 6),

    @Long2 as decimal(18, 6))

    Returns decimal(18, 6) With SchemaBinding

    As

    Begin

    Declare @dLat1InRad as float(53)

    Set @dLat1InRad = @Lat1 * ( PI() / 180.0 )

    Declare @dLong1InRad as float(53)

    Set @dLong1InRad = @Long1 * ( PI() / 180.0 )

    Declare @dLat2InRad as float(53)

    Set @dLat2InRad = @Lat2 * ( PI() / 180.0 )

    Declare @dLong2InRad as float(53)

    Set @dLong2InRad = @Long2 * ( PI() / 180.0 )

    Declare @dLongitude as float(53)

    Set @dLongitude = @dLong2InRad - @dLong1InRad

    Declare @dLatitude as float(53)

    Set @dLatitude = @dLat2InRad - @dLat1InRad

    /* Intermediate result a. */

    Declare @a as float(53)

    Set @a = SQUARE( SIN( @dLatitude / 2.0 ) ) + COS( @dLat1InRad ) * COS( @dLat2InRad ) * SQUARE( SIN( @dLongitude / 2.0 ) )

    /* Intermediate result c (great circle distance in Radians). */

    Declare @C as real

    Set @C = 2.0 * ATN2( SQRT( @a ), SQRT( 1.0 - @a ) )

    Declare @EarthRadius as decimal(18, 6)

    Set @EarthRadius = 3956.0 /* miles */

    Declare @dDistance as decimal(18, 6)

    Set @dDistance = @EarthRadius * @C

    Return (@dDistance)

    End

    Thanks Matt. I've got some testing to do, now. 🙂 I'll be back.

    --Jeff Moden


    RBAR is pronounced "ree-bar" and is a "Modenism" for Row-By-Agonizing-Row.
    First step towards the paradigm shift of writing Set Based code:
    ________Stop thinking about what you want to do to a ROW... think, instead, of what you want to do to a COLUMN.

    Change is inevitable... Change for the better is not.


    Helpful Links:
    How to post code problems
    How to Post Performance Problems
    Create a Tally Function (fnTally)

  • mzak (7/21/2010)


    I figured Jeff would mention this shortly after I posted the requested T-SQL so I was anticipating it :-).

    Nope... Wasn't even going to go there because I did understand the purpose of the article. That being said, looks like someone beat me to it anyway. 😉

    --Jeff Moden


    RBAR is pronounced "ree-bar" and is a "Modenism" for Row-By-Agonizing-Row.
    First step towards the paradigm shift of writing Set Based code:
    ________Stop thinking about what you want to do to a ROW... think, instead, of what you want to do to a COLUMN.

    Change is inevitable... Change for the better is not.


    Helpful Links:
    How to post code problems
    How to Post Performance Problems
    Create a Tally Function (fnTally)

  • Mike C (7/22/2010)


    Cool, glad it worked well for you. Another optimization you might try is using the t-sql "returns null on null input" option, which allows sql server to short-circuit null handling without needing to even start running your clr code (you could then get rid of the explicit .IsNull checks in the clr code).

    The diff between decimal and double is that double is a binary approximation of your values (based on ieee 854 std I believe), so you lose some scale accuracy. Decimal is an exact representation of your decimal values, related to the old binary coded decimal system. The important thing is that all the Math lib functions you're using deal in double data type, and those implicit conversions cost you. For a spatial data app I'd expect double to be "close enough" in most cases. If you need more accuracy than the double data type provides you'll probably need to use a different math library.

    Mike C

    Very cool. I was not aware of the "RETURNS NULL ON NULL INPUT" udf option.

    Thanks again Mike.

Viewing 4 posts - 31 through 33 (of 33 total)

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