• Jeff Moden (10/5/2010)


    If you want (don't worry about the CLR side... we know that's good), post all of the code YOU are using to setup the test, the function, and the Tally Table and I'll try that on my machine to see if I can duplicate the problem you're having. I have both a 2k5 and 2k8 machine at home to test on now.

    And, yes... I realize that much of the code may be what's already been posted and much of it may be mine. Since I'm trying to duplicate your problem, I wanted you to post the actual code you used so I can try and find a difference.

    Thanks, Pavel.

    Jeff,

    here is a complete script and also profiler output:

    --Create TestDB

    CREATE DATABASE [TestDB]

    COLLATE Latin1_General_CI_AS

    GO

    --Use TestDB

    USE [TestDB]

    GO

    --Create and populate tally table

    SELECT TOP 11000

    IDENTITY(INT, 1, 1) AS N

    INTO dbo.Tally

    FROM sys.all_objects o1, sys.all_objects

    GO

    --Add Clustered Index on Tally table

    ALTER TABLE dbo.Tally

    ADD CONSTRAINT PK_Tally PRIMARY KEY CLUSTERED (N) WITH FILLFACTOR = 100

    GO

    --Create and populate CsvTest table (doesn't matter whether the table has Clustered index or it is simply heap)

    SELECT TOP (10000) --Controls the number of rows in the test table

    ISNULL(ROW_NUMBER() OVER (ORDER BY(SELECT NULL)),0) AS RowNum,

    (

    SELECT CAST(STUFF( --=== STUFF get's rid of the leading comma

    ( --=== This builds CSV row with a leading comma

    SELECT TOP (1333) --Controls the number of CSV elements in each row

    ','+CAST(ABS(CHECKSUM(NEWID()))%100000 AS VARCHAR(10))

    FROM dbo.Tally t3 --Classic cross join pseudo-cursor

    CROSS JOIN dbo.Tally t4 --can produce row sets up 121 million.

    WHERE t1.N <> t3.N --Without this line, all rows would be the same

    FOR XML PATH('')

    )

    ,1,1,'') AS VARCHAR(8000))

    ) AS CsvParameter

    INTO CsvTest

    FROM dbo.Tally t1 --Classic cross join pseudo-cursor

    CROSS JOIN dbo.Tally t2; --can produce row sets up 121 million.

    GO

    --Create Split Tally Function

    CREATE FUNCTION dbo.Split8KTallyM (

    @Parameter VARCHAR(8000),

    @Delimiter VARCHAR(1)

    )

    RETURNS @Result TABLE (ItemNumber INT, ItemValue INT) AS

    BEGIN

    INSERT INTO @Result

    (ItemNumber, ItemValue)

    SELECT CAST(ROW_NUMBER() OVER (ORDER BY N) AS INT) AS ItemNumber,

    SUBSTRING(@Parameter,N,CHARINDEX(@Delimiter,@Parameter+@Delimiter,N)-N) AS ItemValue

    FROM dbo.Tally

    WHERE N BETWEEN 1 AND LEN(@Parameter)+1

    AND SUBSTRING(@Delimiter+@Parameter,N,1) = @Delimiter; --Notice how we find the comma

    RETURN

    END;

    GO

    --Tally Test

    DECLARE @RowNum INT, @ItemNumber INT, @ItemValue INT;

    SELECT

    @RowNum = D.RowNum,

    @ItemNumber = V.ItemNumber,

    @ItemValue = V.ItemValue

    FROM dbo.CsvTest D

    CROSS APPLY dbo.Split8KTallyM(D.CsvParameter, ',') V

    GO