C# sql server性能
我们在ETL过程中使用CLR函数来集中特定的数据转换和数据检查逻辑。这些函数非常基本,不需要数据访问,并且具有确定性,因此允许并行 例如:C# sql server性能,c#,sql-server,sqlclr,C#,Sql Server,Sqlclr,我们在ETL过程中使用CLR函数来集中特定的数据转换和数据检查逻辑。这些函数非常基本,不需要数据访问,并且具有确定性,因此允许并行 例如: [SqlFunction(DataAccess = DataAccessKind.None, IsDeterministic = true, SystemDataAccess = SystemDataAccessKind.None, IsPrecise = true)] public static bool check_smallint(string inp
[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
通过创建新连接或为每个函数调用分配内存的开销。因此,解决方案可以是连接/内存池
这不是你需要担心的事情。您没有分配内存(当然,您分配的是函数中所需的字符串和内容,没有任何内容可以共享/重用)。此外,连接也不是你必须担心的事情
除了性能外,这工作正常
您的代码正在做一些难以置信的…异常…缓慢的事情:抛出异常而不是执行检查异常是一种扩展操作,应用于处理异常情况(只有100/200条记录具有null
-或无效值,它将减慢1000000条记录的查询速度)。错误的输入格式或数据库列中的null
值…并不例外(这种编程风格-异常而不是检查-在Python等其他语言中是允许的,甚至是鼓励的。我通常会在C#中避免它。当然,在性能有问题的情况下,它不适用)
注意:String.IsNullOrWhiteSpace(input)
将为null
输入或仅由空格构成的字符串返回true
(替换Trim()
和NullReferenceException
内容)。其他一切(FormatException
,对于不是整数或带有OverflowException
的过大数字的输入文本)都由Int16.TryParse()处理。对于有效输入而言,代码更短(并且稍快),但对于无效输入而言,代码要快很多倍。我将此作为一个单独的答案,而不是对@Adriano的答案发表评论,这样就不太可能遗漏它(因为不是每个人都阅读所有的评论)
除了按照建议更改方法外,您还应该为所有输入/输出参数和返回值使用中的适当数据类型。使用它们有一些重要的区别和好处,例如它们都具有.IsNull
属性。差异的完整列表信息太多,无法放在这里,但我在下面的文章中记录了它:
调整@Adriano的代码以使用适当的类型将为您带来以下好处:
公共静态SqlBoolean检查\u smallint(SqlString输入)
{
if(input.IsNull)
返回true;
if(input.Value.Trim()==String.Empty)
返回true;
短期价值;
返回Int16.TryParse(input.Value,out值);
}
OUT
需要为TryParse方法值参数指定。@AdrianoRepetti+1用于更好的方法(即不依赖异常)。仅供参考,另外一个改进是对参数使用适当的SqlTypes
类型,而不是.NET类型。我添加了一个更详细的解释。谢谢你的评论。我们现在正在尝试。我的投票:我写的代码和普通C#代码一样,我不知道使用SqlXyz类型有什么好处。很高兴知道,我有一些大量使用的功能,将有很大的好处,任何改进@阿德里亚诺雷佩蒂,谢谢。我希望这些信息能有所帮助。还可以查看本系列的其余部分:)。当然,总是有(我是这本书的作者)。
public static bool check_smallint(string input)
{
if (String.IsNullOrWhiteSpace(input))
return true;
short value;
return Int16.TryParse(input, out value);
}