Jasne i ciemne strony baz danych

… w szczególności MS SQL Server ;-)

SQL Server – REPLACE (T-SQL kontra CLR) – dogrywka

Posted by C3PO w dniu 28 lipca 2010


Na początku bieżącego miesiąca podjąłem próbę przetestowania pod kątem wydajności napisanego w CLR zamiennika dla systemowej funkcji REPLACE w SQL Server 2008. Jednak Marek Adamczuk (dzięki, Marek) zwrócił mi uwagę na fakt, że moja funkcja ufn_clr_Replace zawsze uwzględniała wielkość liter w napisach podawanych jako parametry funkcji. Postanowiłem więc stworzyć alternatywną implementację funkcji ufn_clr_Replace:

using System;
using System.Data;
using System.Data.SqlClient;
using System.Data.SqlTypes;
using Microsoft.SqlServer.Server;
using System.Text.RegularExpressions;

public partial class UserDefinedFunctions
{
  [Microsoft.SqlServer.Server.SqlFunction]
  [return: SqlFacet(MaxSize = -1)]
  public static SqlString ufn_clr_Replace(
      [SqlFacet(MaxSize = -1)]
        string Input,
      [SqlFacet(MaxSize = -1)]
        string ToReplace,
      [SqlFacet(MaxSize = -1)]
        string Replacement,
        bool IsCaseSensitive)
  {
    return new SqlString(
      Regex.Replace(
        Input,
        Regex.Escape(ToReplace),
        Replacement,
        IsCaseSensitive == false ? RegexOptions.IgnoreCase : RegexOptions.None
      )
    );
  }
};

Co się zmieniło? Przede wszystkim zrezygnowałem z użycia metody Replace klasy String. Zamiast tego użyłem metody Replace klasy Regex (implementacja wyrażeń regularnych w .NET). Dodałem parametr IsCaseSensitive, który decyduje, czy ma być rozróżniana wielkość liter.

Test przeprowadziłem za pomocą analogicznego kodu, co w przypadku mojej poprzedniej próby.

Wyniki są dość jednoznaczne. Systemowa funkcja REPLACE wypada lepiej w mniej więcej 3400 na 5300 przypadków, a w przypadkach, gdy działa wolniej, różnica w czasie działania porównywanych funkcji jest znikoma (w granicach marginesu błędu). Zbliżony wynik otrzymałem też, gdy nie użyłem metody Escape klasy Regex na parametrze ToReplace (metoda ta pozwala zignorować ewentualne wyrażenia regularne w napisie będącym wzorcem do znalezienia i zastąpienia – używając jej uzyskałem „zwyczajną” funkcję REPLACE, która nie wykorzystuje wyrażeń regularnych).

Advertisements

Skomentuj

Wprowadź swoje dane lub kliknij jedną z tych ikon, aby się zalogować:

Logo WordPress.com

Komentujesz korzystając z konta WordPress.com. Log Out / Zmień )

Zdjęcie z Twittera

Komentujesz korzystając z konta Twitter. Log Out / Zmień )

Facebook photo

Komentujesz korzystając z konta Facebook. Log Out / Zmień )

Google+ photo

Komentujesz korzystając z konta Google+. Log Out / Zmień )

Connecting to %s

 
%d bloggers like this: