c# - CLR sql server 性能

标签 c# sql-server sqlclr

我们在 ETL 过程中使用 CLR 函数来集中处理特定的数据转换和数据检查逻辑。这些功能相当基本,不需要数据访问,并且是确定性的,因此允许并行。

例如:

[SqlFunction(DataAccess = DataAccessKind.None, IsDeterministic = true, SystemDataAccess = SystemDataAccessKind.None, IsPrecise = true)]
public static bool check_smallint(string input)
{
    string teststring;
    try
    {
        teststring = input.Trim(' ').Replace('-', '0');
        if (teststring.Length == 0)
        {
            teststring = "0";
        }
        Convert.ToInt16(teststring);
    }
    catch (NullReferenceException)
    {
        return true;
    }
    catch (FormatException)
    {
        return false;
    }
    catch (OverflowException)
    {
        return false;
    }
    return true;
}

除了性能之外,这工作正常。查询速度大大降低,这在处理大型数据集(数百万行或更多)时造成了麻烦。

到目前为止,我们还没有发现真正了解 SQL CLR 体系结构的人,但我们收到的一个建议是,这可能是由创建新连接或为每个函数调用分配内存的开销引起的。所以一个解决方案可能是连接/内存池。

请不要提出不同的解决方案,我们已经在考虑它们,例如内联 sql,或完全不同的方法。标准的 sql 函数在许多情况下是没有选择的,因为缺乏错误引发。

附言。我们正在使用 SQL 2008R2。

最佳答案

by the overhead of creating a new connection or allocating memory for every function-call. So a solution could be connection / memory pooling.

这不是您在 C# 方面需要担心的事情。您不是在分配内存(当然,您是在分配字符串和函数内部所需的东西,没有任何东西可以汇集/重用)。此外,您不必担心连接问题。

This works fine except for performance.

您的代码正在做一些令人难以置信的事情...异常...缓慢:抛出异常而不是执行检查。 异常是一种扩展操作,应该用于处理异常情况(只有 100/200 条记录具有 null - 或无效 - 值,它会减慢查询速度超过 1,000,000 条记录)。错误的输入格式或数据库列中的 null 值......并不是异常(exception)(这种编程风格 - 异常(exception)而不是检查 - 允许并且甚至在其他语言中受到鼓励,例如Python。我通常会在 C# 中避免使用它。可以肯定的是,在性能有问题的情况下它不合适。

public static bool check_smallint(string input)
{
    if (String.IsNullOrWhiteSpace(input))
        return true;

    short value;
    return Int16.TryParse(input, out value);
}

请注意:String.IsNullOrWhiteSpace(input) 将为 null 输入或仅由空格组成的字符串返回 true(替换您的 Trim()NullReferenceException 东西)。其他一切(FormatException 对于不是整数的输入文本或带有 OverflowException 的太大数字)由 Int16.TryParse() 处理。对于有效输入,代码更短(并且稍微快),但对于无效输入,它快很多倍

关于c# - CLR sql server 性能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26340521/

相关文章:

c# - 使用依赖属性设置标签内容

c# - sqlFileStream 系统.ComponentModel.Win32Exception : The request is not supported

c# - 如何在现有行下方的 DataTable 中添加新行

C# - MySQL - MySql.Data.MySqlClient.MySqlStream.ReadPacket()

java - Java EE Web 应用程序中的无效字符串或缓冲区长度异常

sql - TOP 减慢查询速度

sql-server - 用于递增的 SQL Server 或 SSIS 代码

.net - SQLCLR 使用错误版本的 .NET Framework

c# - 如何在不升级到 MSDTC 的情况下在 SQLCLR 中使用 TransactionScope

c# - 由于 "make-local-hook",无法为 emacs 加载 C# 模式