Deterministic UDF slower than Non-Deterministic?

  • I'm no .NET programmer but i did a function that manipulates string inputs and if i set IsDeterministic=true on the CLR function it consumes around 40% cpu and also takes 40% longer to complete compared to not setting the IsDeterministic flag.

    As im no CLR Integration expert, anyone cares to explain this?

    --
    Thiago Dantas
    @DantHimself

  • Can't help in the CLR area but if you demonstrate the string manipulation you're trying to do in a CLR, I can try to beat it in T-SQL. I've been successful at it a couple of times. Like anything else, "It Depends". 😉

    --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)
    Intro to Tally Tables and Functions

  • alright, here it goes.

    T-SQL code (var names and common words are in portuguese)

    CREATE FUNCTION [dbo].[UF_TRATASTRING]

    (

    @PALAVRA NVARCHAR(3000)

    )

    RETURNS NVARCHAR(3000)

    AS BEGIN

    DECLARE @INDICE INT

    SET @INDICE = 0

    DECLARE @P NVARCHAR(3000)

    SET @P = ''

    DECLARE @TEMP NVARCHAR(3000)

    SET @TEMP = ''

    DECLARE @ACERTA NVARCHAR(3000)

    SET @ACERTA = @PALAVRA

    --trim the word

    SET @ACERTA = LTRIM(RTRIM(LOWER(@ACERTA)))

    IF LEN(@ACERTA) > 1

    BEGIN

    --capitalize first character

    SET @ACERTA = UPPER(SUBSTRING(@ACERTA, 1, 1)) + SUBSTRING(@ACERTA, 2, LEN(@ACERTA) - 1)

    --remove excess dots

    WHILE CHARINDEX('..', @ACERTA) > 0

    BEGIN

    SET @ACERTA = REPLACE(REPLACE(@ACERTA, '..', ''), '.', '')

    END

    --space after dot

    SET @ACERTA = REPLACE(@ACERTA, '.', '. ')

    -- remove excess spaces

    WHILE CHARINDEX(' ', @ACERTA) > 0

    BEGIN

    SET @ACERTA = REPLACE(@ACERTA, ' ', ' ')

    END

    --remove invalid characters

    SET @INDICE = 1

    WHILE @INDICE <= DATALENGTH(@ACERTA)

    BEGIN

    IF ( ASCII(SUBSTRING(@ACERTA, @INDICE, 1)) < 32

    OR ASCII(SUBSTRING(@ACERTA, @INDICE, 1)) = 63

    OR ASCII(SUBSTRING(@ACERTA, @INDICE, 1)) = 39

    )

    AND ASCII(SUBSTRING(@ACERTA, @INDICE, 1)) <> 10

    AND ASCII(SUBSTRING(@ACERTA, @INDICE, 1)) <> 13

    SET @ACERTA = REPLACE(@ACERTA,

    CHAR(ASCII(SUBSTRING(@ACERTA, @INDICE, 1))),

    ' ')

    SET @INDICE = @INDICE + 1

    END

    --capitalize initials

    SET @P = @ACERTA

    SET @INDICE = 0

    WHILE CHARINDEX(' ', @P) > 0

    BEGIN

    SET @INDICE = @INDICE + CHARINDEX(' ', @P)

    SET @ACERTA = REPLACE(@ACERTA,

    SUBSTRING(@ACERTA, @INDICE, 2),

    UPPER(SUBSTRING(@ACERTA, @INDICE, 2)))

    SET @TEMP = ''

    SET @TEMP = SUBSTRING(@P, CHARINDEX(' ', @P) + 1, LEN(@P))

    SET @P = @TEMP

    END

    -- change common words

    SET @ACERTA = REPLACE(@ACERTA, ' DA ', ' da ')

    SET @ACERTA = REPLACE(@ACERTA, ' DE ', ' de ')

    SET @ACERTA = REPLACE(@ACERTA, ' DO ', ' do ')

    SET @ACERTA = REPLACE(@ACERTA, ' E ', ' e ')

    SET @ACERTA = REPLACE(@ACERTA, ' DAS ', ' das ')

    SET @ACERTA = REPLACE(@ACERTA, ' DOS ', ' dos ')

    SET @ACERTA = REPLACE(@ACERTA, ' COM ', ' com ')

    SET @ACERTA = REPLACE(@ACERTA, ' UM ', ' um ')

    END

    ELSE

    SET @ACERTA = UPPER(SUBSTRING(@ACERTA, 1, 1))

    RETURN ISNULL(@ACERTA, '')

    END

    and the VB.NET code (note, i didnt write any, the VB one is used inside our web app and the T-SQL was used on the ETL process and inside some SPs, i myself don't understand very well what the VB code is doing, all i know is it returns the same as above but faster)

    <Microsoft.SqlServer.Server.SqlFunction(Name:="UF_TRATASTRING")> _

    Public Shared Function TRATASTRING(<SqlFacet(MaxSize:=3000)> ByVal strTexto As String) As <SqlFacet(MaxSize:=3000)> String

    Dim strCharAnterior As String = "."

    Dim strChar As String

    Dim x As Integer = 0

    Dim intPosicaoPrimeiroEspaco As Integer = 0

    Dim strRetorno As New StringBuilder

    Dim strPrimeiraPalavra As String = ""

    If strTexto = Nothing Then

    strTexto = ""

    Else

    strTexto = strTexto.ToLower

    For Each strChar In strTexto

    If Asc(strChar) < 32 AndAlso Asc(strChar) <> 13 AndAlso Asc(strChar) <> 10 Then

    strChar = " "

    End If

    If Asc(strCharAnterior) = 13 OrElse Asc(strCharAnterior) = 10 Then

    strCharAnterior = "."

    End If

    If strCharAnterior = " " Then

    If intPosicaoPrimeiroEspaco = 0 Then

    intPosicaoPrimeiroEspaco = x

    End If

    If strChar <> " " Then

    If strTexto.Substring(x).Length >= 2 Then

    Select Case strTexto.Substring(x, 2)

    Case "e "

    strRetorno.Append(strChar)

    Case Else

    If strTexto.Substring(x).Length >= 3 Then

    Select Case strTexto.Substring(x, 3)

    Case "da "

    strRetorno.Append(strChar)

    Case "de "

    strRetorno.Append(strChar)

    Case "do "

    strRetorno.Append(strChar)

    Case Else

    If strTexto.Substring(x).Length >= 4 Then

    Select Case strTexto.Substring(x, 4)

    Case "das "

    strRetorno.Append(strChar)

    Case "dos "

    strRetorno.Append(strChar)

    Case Else

    strRetorno.Append(strChar.ToUpper)

    End Select

    Else

    strRetorno.Append(strChar.ToUpper)

    End If

    End Select

    Else

    strRetorno.Append(strChar.ToUpper)

    End If

    End Select

    Else

    If x < strTexto.Length - 1 AndAlso strTexto.Substring(x, 1) = strTexto.Substring(x, 1).ToUpper AndAlso strTexto.Substring(x + 1, 1) = strTexto.Substring(x + 1, 1).ToLower Then

    strRetorno.Append(strChar.ToUpper)

    Else

    strRetorno.Append(strChar)

    End If

    End If

    End If

    ElseIf strCharAnterior <> "." Then

    strRetorno.Append(strChar)

    Else

    If strChar = " " Then

    strChar = "."

    If strRetorno.Length > 0 AndAlso strCharAnterior <> "." Then

    strRetorno.Append(" ")

    End If

    strRetorno.Append(strChar.ToUpper)

    Else

    If x < strTexto.Length - 1 AndAlso strTexto.Substring(x, 1) = strTexto.Substring(x, 1).ToUpper AndAlso strTexto.Substring(x + 1, 1) = strTexto.Substring(x + 1, 1).ToLower Then

    strRetorno.Append(strChar.ToUpper)

    Else

    strRetorno.Append(strChar)

    End If

    End If

    End If

    strCharAnterior = strChar

    x += 1

    Next

    End If

    Return New SqlString(strRetorno.ToString().Replace(".", ". ").Trim)

    End Function

    --
    Thiago Dantas
    @DantHimself

  • Try this, Thiango... it may even give your .Net code a run for it's money. It's 32 to 64 times faster than the T-SQL Function you wrote. If you didn't have the requirement to do "initial caps", it would be faster still and we could turn it into an iTVF instead of a relatively slow scalar function.

    (Side bar... your function didn't work correctly... it would get rid of all periods if ANY two were adjacent)

    Although it looks very wierd, you have to understand that nested REPLACE's are the fastest thing this side of a bullet. Let me know if you have any questions. Here's the function... it's heavily documented, as well...

    CREATE FUNCTION dbo.UF_TRATASTRING

    (@PALAVRA NVARCHAR(4000))

    --===== Created by Jeff Moden

    RETURNS NVARCHAR(4000) AS

    BEGIN

    SELECT @PALAVRA =

    REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE( --Dedupe Spaces (Good past 8k).

    REPLACE( --Add space after periods.

    REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE( --Dedupe Periods (Good past 8k).

    REPLACE(REPLACE(REPLACE(REPLACE(REPLACE( --Remove unwanted characters

    REPLACE(REPLACE(REPLACE(REPLACE(REPLACE( --Remove unwanted characters

    REPLACE(REPLACE(REPLACE(REPLACE(REPLACE( --Remove unwanted characters

    REPLACE(REPLACE(REPLACE(REPLACE(REPLACE( --Remove unwanted characters

    REPLACE(REPLACE(REPLACE(REPLACE(REPLACE( --Remove unwanted characters

    REPLACE(REPLACE(REPLACE(REPLACE(REPLACE( --Remove unwanted characters

    REPLACE(REPLACE( --Remove unwanted characters

    LTRIM(RTRIM(LOWER(@PALAVRA COLLATE LATIN1_GENERAL_BIN ))) --Trim and change to lower case.

    ,NCHAR(0),'') ,NCHAR(1),'') ,NCHAR(2),'') ,NCHAR(3),'') ,NCHAR(4),'') --Remove unwanted characters

    ,NCHAR(5),'') ,NCHAR(6),'') ,NCHAR(7),'') ,NCHAR(8),'') ,NCHAR(9),'') --Remove unwanted characters

    ,NCHAR(11),''),NCHAR(12),''),NCHAR(14),''),NCHAR(15),''),NCHAR(16),'') --Remove unwanted characters

    ,NCHAR(17),''),NCHAR(18),''),NCHAR(19),''),NCHAR(20),''),NCHAR(21),'') --Remove unwanted characters

    ,NCHAR(22),''),NCHAR(23),''),NCHAR(24),''),NCHAR(25),''),NCHAR(26),'') --Remove unwanted characters

    ,NCHAR(27),''),NCHAR(28),''),NCHAR(29),''),NCHAR(30),''),NCHAR(31),'') --Remove unwanted characters

    ,NCHAR(39),''),NCHAR(63),'') --Remove unwanted characters

    ,N'.................................',N'.') --32+1 Dedupe Periods

    ,N'.................',N'.') --16+1

    ,N'.........',N'.') --8+1

    ,N'.....',N'.') --4+1

    ,N'...',N'.') --2+1

    ,N'..',N'.') --1+1

    ,N'.',N'. ') --Add space after periods

    ,N' ',N' ') --32+1 Dedupe Spaces

    ,N' ',N' ') --16+1

    ,N' ',N' ') --8+1

    ,N' ',N' ') --4+1

    ,N' ',N' ') --2+1

    ,N' ',N' ') --1+1

    --===== Do the initial caps thing.

    -- The cascaded CTE's build an on-the-fly-memory-only-tally "table".

    ;WITH

    E1(N) AS ( --=== Create eight 1's

    SELECT 1 UNION ALL SELECT 1 UNION ALL

    SELECT 1 UNION ALL SELECT 1 UNION ALL

    SELECT 1 UNION ALL SELECT 1 UNION ALL

    SELECT 1 UNION ALL SELECT 1 --8

    ),

    E2(N) AS (SELECT 1 FROM E1 a, E1 b), --64

    E4(N) AS (SELECT 1 FROM E2 a, E2 b), --4,096

    cteTally(N) AS (SELECT ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) FROM E4)

    SELECT @PALAVRA = STUFF(@PALAVRA,t.N,1,UPPER(SUBSTRING(@PALAVRA,t.N,1)))

    FROM cteTally t

    WHERE t.N <= LEN(@PALAVRA COLLATE LATIN1_GENERAL_BIN )

    AND SUBSTRING(@PALAVRA COLLATE LATIN1_GENERAL_BIN,t.N-1,2) LIKE N'[ ][^ ]' --Space followed by nonblank

    ;

    --===== Change common words back to lower case

    SELECT @PALAVRA = REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(

    @PALAVRA COLLATE LATIN1_GENERAL_BIN

    ,N' DA ' , N' da ' )

    ,N' DE ' , N' de ' )

    ,N' DO ' , N' do ' )

    ,N' E ' , N' e ' )

    ,N' DAS ', N' das ')

    ,N' DOS ', N' dos ')

    ,N' COM ', N' com ')

    ,N' UM ' , N' um ' )

    --==== First character Init and Null conversion

    RETURN ISNULL(STUFF(@PALAVRA,1,1,UPPER(SUBSTRING(@PALAVRA,1,1))),N'')

    END

    --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)
    Intro to Tally Tables and Functions

  • wow Jeff, thats a nice load of replaces lol. ill test it first thing on monday and post the results against the old T-SQL and the CLR functions. Thanks for the help

    --
    Thiago Dantas
    @DantHimself

  • dant12 (7/31/2010)


    wow Jeff, thats a nice load of replaces lol. ill test it first thing on monday and post the results against the old T-SQL and the CLR functions. Thanks for the help

    Heh... and don't think for a minute that I actually typed all that stuff. 😛 Looking forward to your tests and thanks for the feedback.

    --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)
    Intro to Tally Tables and Functions

  • Jeff Moden (8/1/2010)


    dant12 (7/31/2010)


    wow Jeff, thats a nice load of replaces lol. ill test it first thing on monday and post the results against the old T-SQL and the CLR functions. Thanks for the help

    Heh... and don't think for a minute that I actually typed all that stuff. 😛 Looking forward to your tests and thanks for the feedback.

    how'd u do it then?

    --
    Thiago Dantas
    @DantHimself

  • dant12 (8/1/2010)


    Jeff Moden (8/1/2010)


    dant12 (7/31/2010)


    wow Jeff, thats a nice load of replaces lol. ill test it first thing on monday and post the results against the old T-SQL and the CLR functions. Thanks for the help

    Heh... and don't think for a minute that I actually typed all that stuff. 😛 Looking forward to your tests and thanks for the feedback.

    how'd u do it then?

    I let the machine do it. Here's an example for a project I'm working on right now. The code is really easy to convert from a basic bit of boiler plate code... the addition of a CR here and there is all that needs to be done to make the output exactly the way I want it...

    DECLARE @SQL1 VARCHAR(8000),

    @SQL2 VARCHAR(8000),

    @SQL3 VARCHAR(8000)

    SELECT @SQL1 = ISNULL(@SQL1,'') + 'REPLACE(' + CASE WHEN (t.n-1)%5 = 4 THEN CHAR(10) ELSE '' END

    FROM dbo.Tally t

    WHERE t.N BETWEEN 1 AND 128

    AND CHAR(t.N-1) COLLATE LATIN1_GENERAL_BIN NOT LIKE '[a-zA-Z0-9. ,]' COLLATE LATIN1_GENERAL_BIN

    SELECT @SQL2 = 'DirtyString COLLATE LATIN1_GENERAL_BIN'

    SELECT @SQL3 = ISNULL(@SQL3,'')+ ',CHAR('+CAST(t.N-1 AS VARCHAR(3))+'),'''')'+ CASE WHEN (t.n-1)%5 = 4 THEN CHAR(10) ELSE '' END

    FROM dbo.Tally t

    WHERE t.N BETWEEN 1 AND 128

    AND CHAR(t.N-1) COLLATE LATIN1_GENERAL_BIN NOT LIKE '[a-zA-Z0-9. ,]' COLLATE LATIN1_GENERAL_BIN

    PRINT @SQL1

    PRINT @SQL2

    PRINT @SQL3

    --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)
    Intro to Tally Tables and Functions

  • dunno whats wrong with your function but it performed way slower than the old one

    DECLARE @a DATETIME = GETDATE() -- CLR

    SELECT DBO.UF_TRATASTRING(NOME_DEV) FROM TB_DEVEDOR

    SELECT DATEDIFF(MS,@A,GETDATE())

    GO

    DECLARE @a DATETIME = GETDATE() -- JEFF T-SQL

    SELECT DBO.UF_TRATASTRING2(NOME_DEV) FROM TB_DEVEDOR

    SELECT DATEDIFF(MS,@A,GETDATE())

    GO

    DECLARE @a DATETIME = GETDATE() -- OLD SQL

    SELECT DBO.UF_TRATASTRING3(NOME_DEV) FROM TB_DEVEDOR

    SELECT DATEDIFF(MS,@A,GETDATE())

    GO

    /*

    FIRST RUN

    CLR: CPU time = 5678 ms, elapsed time = 6110 ms.

    JEFF TSQL: CPU time = 788539 ms, elapsed time = 1647436 ms.

    OLD TSQL: CPU time = 103164 ms, elapsed time = 119757 ms.

    SECOND RUN

    CLR: CPU time = 5709 ms, elapsed time = 6146 ms.

    JEFF TSQL: CPU time = 792173 ms, elapsed time = 1553814 ms.

    OLD TSQL: CPU time = 103101 ms, elapsed time = 119565 ms.

    */

    that table has 646184 rows and the column is of variable lenght. those results are from my development machine, ill test it a better one and post the results again

    ps: this post has derailed greatly lol. I'm still curious about my deterministic vs non-deterministic inquiry

    ///EDIT

    here goes the results from our production-like server (table with 381519 records, same query as above)

    /*

    FIRST RUN

    CLR: CPU time = 2641 ms, elapsed time = 9114 ms.

    JEFF TSQL: CPU time = 16844 ms, elapsed time = 17604 ms.

    OLD TSQL: CPU time = 66484 ms, elapsed time = 72546 ms.

    SECOND RUN

    CLR: CPU time = 2562 ms, elapsed time = 13587 ms.

    JEFF TSQL: CPU time = 17094 ms, elapsed time = 21931 ms.

    OLD TSQL: CPU time = 66484 ms, elapsed time = 72956 ms.

    */

    now im really puzzled, why on my dev machine it got really really slow

    ///EDIT 2

    ran the queries again on the same server as above but on a different database on a table with 7559955 records. the results were

    /*

    FIRST RUN

    CLR: CPU time = 58829 ms, elapsed time = 440024 ms.

    JEFF TSQL: CPU time = 395968 ms, elapsed time = 776934 ms.

    OLD TSQL: CPU time = 1607407 ms, elapsed time = 1755791 ms.

    SECOND RUN

    CLR: CPU time = 60657 ms, elapsed time = 213006 ms.

    JEFF TSQL: CPU time = 385547 ms, elapsed time = 408962 ms.

    OLD TSQL: CPU time = 1607187 ms, elapsed time = 1764218 ms.

    */

    sorry Jeff, seems the CLR beat you this time

    --
    Thiago Dantas
    @DantHimself

  • dant12 (8/2/2010)


    dunno whats wrong with your function but it performed way slower than the old one

    Heh... dunno what's wrong with your machine, db, or table, but the function I wrote was just like I said... 32 to 64 times faster depending on whether or not the heartbeat of the machine kicked in during the test run.

    I'll set it all up again tonight to see what the difference is... any chance of you providing the table definition and some readily consumable sample data? See the first link in my sginature line below for how to do that.

    --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)
    Intro to Tally Tables and Functions

  • yeah sure ill send you a .csv if your willing to play with it, but i wouldnt bother so much. you already gave me lots of ideas with both ur sample codes

    --
    Thiago Dantas
    @DantHimself

  • dant12 (8/2/2010)


    yeah sure ill send you a .csv if your willing to play with it, but i wouldnt bother so much. you already gave me lots of ideas with both ur sample codes

    That would be very cool. The reason I'm asking is because I want to try to find what went wrong. On 8K rows, your function took about 16 seconds to run and mine took 1/4 of a second. Yup... I've got an older slower machine but that a huge difference from what you posted as time and I wanted to find out why.

    Thanks.

    --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)
    Intro to Tally Tables and Functions

  • Jeff Moden (8/3/2010)


    dant12 (8/2/2010)


    yeah sure ill send you a .csv if your willing to play with it, but i wouldnt bother so much. you already gave me lots of ideas with both ur sample codes

    That would be very cool. The reason I'm asking is because I want to try to find what went wrong. On 8K rows, your function took about 16 seconds to run and mine took 1/4 of a second. Yup... I've got an older slower machine but that a huge difference from what you posted as time and I wanted to find out why.

    Thanks.

    http://www.mediafire.com/?phfjo9005ug2wl2

    thats the whole 676k sample of the entire table along with the generated create table script

    --
    Thiago Dantas
    @DantHimself

  • dant12 (8/3/2010)


    Jeff Moden (8/3/2010)


    dant12 (8/2/2010)


    yeah sure ill send you a .csv if your willing to play with it, but i wouldnt bother so much. you already gave me lots of ideas with both ur sample codes

    That would be very cool. The reason I'm asking is because I want to try to find what went wrong. On 8K rows, your function took about 16 seconds to run and mine took 1/4 of a second. Yup... I've got an older slower machine but that a huge difference from what you posted as time and I wanted to find out why.

    Thanks.

    http://www.mediafire.com/?phfjo9005ug2wl2

    thats the whole 676k sample of the entire table along with the generated create table script

    Lunch time, thought I'd give it a go. Can't access your data as it is blocked. Could you upload as a text file a small sample with the create table and insert already done so I can test what I wrote? Also, expected results based on the small sample would help me validate my process.

  • Lynn Pettis (8/3/2010)


    dant12 (8/3/2010)


    Jeff Moden (8/3/2010)


    dant12 (8/2/2010)


    yeah sure ill send you a .csv if your willing to play with it, but i wouldnt bother so much. you already gave me lots of ideas with both ur sample codes

    That would be very cool. The reason I'm asking is because I want to try to find what went wrong. On 8K rows, your function took about 16 seconds to run and mine took 1/4 of a second. Yup... I've got an older slower machine but that a huge difference from what you posted as time and I wanted to find out why.

    Thanks.

    http://www.mediafire.com/?phfjo9005ug2wl2

    thats the whole 676k sample of the entire table along with the generated create table script

    Lunch time, thought I'd give it a go. Can't access your data as it is blocked. Could you upload as a text file a small sample with the create table and insert already done so I can test what I wrote? Also, expected results based on the small sample would help me validate my process.

    tested the mediafire link and worked with no problems, you have winrar installed?

    ill provide a small sample either way

    IF OBJECT_ID('TEMP_TAB') IS NOT NULL

    DROP TABLE TEMP_TAB

    CREATE TABLE TEMP_TAB (NAME VARCHAR(60))

    INSERT INTO TEMP_TAB

    SELECT 'Ponto A - Edicao e Impressao de Prod' UNION ALL

    SELECT '& e S Comercio de Representacoes de Moto' UNION ALL

    SELECT '. Eucelma do Carmo de O Martins' UNION ALL

    SELECT '. Irlane Valquiria de Sena Gomes' UNION ALL

    SELECT '. Lessandro Pinheiro de Oliveira' UNION ALL

    SELECT '00071rosangela Greco Moura Fonseca' UNION ALL

    SELECT '007maria Aprecida Fidelis da S Conceicao' UNION ALL

    SELECT '1 Oficio do Registro Civil e Anexos' UNION ALL

    SELECT '10 Igreja Evangelica Pentecostal O Brasi' UNION ALL

    SELECT '100 /, Milho Verde e Pamonharia Ltda-me' UNION ALL

    SELECT '1000 Razoes Comercio de Artigos do Vestu' UNION ALL

    SELECT '1144851sonia Maria Mendes da Silva' UNION ALL

    SELECT '14 Bis Materiais Para Construcao Ltda -' UNION ALL

    SELECT '1a. Igreja Batista Em Navirai-ms' UNION ALL

    SELECT '2 Andrades Treinamento e Consultoria Ltd' UNION ALL

    SELECT '2 Irmaos Prestadora de Servicos de Telec' UNION ALL

    SELECT '206 Fashion, Ws Couture e San Philipo Co' UNION ALL

    SELECT '21 de Abril Associacao Unica das Pracas' UNION ALL

    SELECT '27maria de Lourdes Bertoldo dos Santos' UNION ALL

    SELECT '2831 Estudio Comunicacao e Design Ltda' UNION ALL

    SELECT '2dulcicleia Fernandes dos Santos' UNION ALL

    SELECT '2-m Restaurante e Choperia Ltda Me' UNION ALL

    SELECT '2mm Eletro Telecomunicacoes Comercio Rep' UNION ALL

    SELECT '3 M Industria e Comercio de Cafe Ltda.' UNION ALL

    SELECT '3 Mmm G Comercio e Representacoes Ltda' UNION ALL

    SELECT '3. Milenio Operadora de Sorteio de Bingo' UNION ALL

    SELECT '3a - Servicos de Filmagens e Locacoes De' UNION ALL

    SELECT '3r Ferraro Importacao e Exportacao Ltda' UNION ALL

    SELECT '4 Rodas Auto Pecas e Vidros Ltda' UNION ALL

    SELECT '4-in Comunicacao e Design Ltda Me' UNION ALL

    SELECT '4u Network - Comercio de Equipamentos E' UNION ALL

    SELECT '87226921katia Maria Andrade Lima' UNION ALL

    SELECT '888782849josue Moreira da Silva' UNION ALL

    SELECT '92322370mirella Maria da C de Carvalho' UNION ALL

    SELECT 'A & J Informatica Brasilia Ltda' UNION ALL

    SELECT 'A & T Comercio de Equipamentos Eletroele' UNION ALL

    SELECT 'A & T Telecom Solucoes Empresariais e Co' UNION ALL

    SELECT 'A . Comercial de Aluminios Braziliense L' UNION ALL

    SELECT 'A + Design Criatividade Grafica e Digita' UNION ALL

    SELECT 'A A Agata Divisorias, Forros, e Pisos Lt' UNION ALL

    SELECT 'A A Francischini & Francischini Ltda Me' UNION ALL

    SELECT 'A Anti Pragas Desinfestacoes Ltda' UNION ALL

    SELECT 'A Associacao DOS Moradores DA Vila Uniao' UNION ALL

    SELECT 'A C D Assessoria Empresarial Ltda Me' UNION ALL

    SELECT 'A C G Compra e Venda de Bens Imoveis Ltd' UNION ALL

    SELECT 'A C N Eventos e Promocoes Artisticas Ltd' UNION ALL

    SELECT 'A C Silva Transportadora Ltda Me' UNION ALL

    SELECT 'A Casa do Hospital Comercio de Produtos' UNION ALL

    SELECT 'A Construlimp Materiais de Construcao E' UNION ALL

    SELECT 'A D de Alcantara Neto-multivendas'

    SELECT * FROM TEMP_TAB

    --
    Thiago Dantas
    @DantHimself

Viewing 15 posts - 1 through 15 (of 23 total)

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