1

I've written the following T-SQL function, but on implementation it seems to be very slow (it basically functions to return a phone number from a string such as "01530 999111 - don't phone in the evening!".

Do any of you marvellously insightful people have any tips for me in order to improve the performance of this function or have any more efficient alternatives to suggest?

ALTER FUNCTION [dbo].[xfnJustNumbers](@inStr varchar(255))
RETURNS [varchar](255)
AS
BEGIN

  DECLARE @outStr varchar(255)
  SELECT @outStr = ''
  DECLARE @charNo int
  SELECT @charNo = 0
  WHILE @CharNo < len(@inStr) begin
    SELECT @CharNo = @CharNo +1
    IF isnumeric(substring(@inStr,@CharNo,1))=1 SELECT @outStr = @outStr + substring(@inStr,@CharNo,1)
  END
  RETURN @outStr

END

Thanks :)

4
  • 3
    Replacing it with a CLR regex based function will likely speed things up. Scalar UDfs are pretty slow in SQL Server. It is important to look at the query and be sure that it is operating on the minimum number of rows. I've seen WITH SCHEMABINDING used on scalar UDFs - Not sure if that has any performance benefit at all. Commented Mar 14, 2011 at 11:49
  • 1
    not sure about the situation but it would definitely help such cases if you had another column for phone number in your table Commented Mar 14, 2011 at 11:51
  • BTW: Don't use IsNumeric as that matches things like +,-,$ you would use LIKE [0-9] or ASCII(@CHR) BETWEEN 48 AND 57 Commented Mar 14, 2011 at 12:20
  • I have opted for Martin's suggestion and on running tests, I've reduced the average execution time by half. Thank you! Commented Mar 14, 2011 at 15:04

1 Answer 1

1

You could probably eke out a bit of additional performance from the TSQL version by trying some of the following.

  1. Only calling it if you establish the string does contain at least one number CASE WHEN COl NOT LIKE '%[0-9]%' THEN '' ELSE [dbo].[xfnJustNumbers](col) END
  2. Storing substring(@inStr,@CharNo,1) and len(@inStr) in variables rather than evaluating them more than once.
  3. Checking ASCII(@chr) rather than calling isnumeric this is likely to be more what you need anyway.
  4. Including the WITH SCHEMABINDING option in the function declaration to ensure that plans using these UDFs do not do unnecessary spools.

Having said all that though I'd use a CLR function using RegularExpressions for this.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.