2011-08-10 41 views
0

我想创建CLR UDF扫描SQL表和读取每一列,总结所有数据 每列(我与大数据集时,像>1000列和20,000,000>rows)。C#CLR UDF扫描SQL表

我想比较申请与并行for loop

每列SUM(COLUMN_NAME) SQL函数使SQL就像

SELECT SUM(COLUMN_1),SUM(COLUMN_2),SUM(COLUMN_3),...,SUM(COLUMN_1000) 

我怎样才能做一个CLR UDF in C#,将做到这一点?

我打算使用数组,所以每次我看行时间我添加它想: array[i]+= sqlValue;

如何做到这一点,这样我就可以在一个stored proc执行他们两个?

column_1 column_2 column_3 .... column_1000 
--------------------------------------------- 
    451  57  253     135 
    251  77  356     965 
    481  15  323     655 
    452  15  135     665 
    ... 
    ...20,000,000 more rows 
+0

请问你的CLR UDF是什么样子?你已经试过了什么?创建一个CLR UDF是有据可查的。 – VVS

+0

按列扫描表并且并行执行for循环?你有一个例子吗? – cMinor

回答

3

所以,你想达到什么是尽千SELECT column_x FROM table,每列,并从手工做加法。

这意味着在相同的行内同一个表中的所有工作数据库1000个并行连接,锁定对方(除非您使用with nolock)。

的好处SELECT sum(column_1), sum(column_2), ...。我看不到一个,我相信你所尝试的将会比让SQL Server做最好的事情慢得多。

编辑:

按照您的要求这里的quick'n'dirty样品,没有测试过,因为我现在手头没有SQL服务器。我假定列long型的,其结果是decimal类型。

public partial class UserDefinedFunctions 
{ 
    private static string GetCommandText(int column) 
    { 
     return string.Format("select column_{0} from table", column); 
    } 

    [Microsoft.SqlServer.Server.SqlFunction(
     DataAccess = DataAccessKind.Read, 
     TableDefinition = "result decimal", 
     FillRowMethodName = "FillRow", 
     SystemDataAccess = SystemDataAccessKind.Read)] 
    public static IEnumerable fnSum(int columnNo) 
    { 
     var values = new List<long>(); 

     using (var cmd = new SqlCommand(GetCommandText(columnNo), new SqlConnection("context connection=true"))) 
     { 
      cmd.Connection.Open(); 
      using (var reader = cmd.ExecuteReader(CommandBehavior.SingleResult | CommandBehavior.CloseConnection)) 
      { 
       while (reader.Read()) 
       { 
        values.Add(reader.GetInt64(0)); 
       } 
      } 
     } 

     return list; 
    } 

    private static void FillRow(object obj, out decimal result) 
    { 
     var values = (List<long>)obj; 

     result = values.Sum(value => (decimal) value); 
    } 
} 
+0

也许只用4个线程,我也愿意做其他复杂的公式,总和是很容易的,但是怎么样,SQR或登录....我需要的是CLR UDF C#扫描列的例子......莫非你点了一个教程? – cMinor

+1

@cMinor,你就不能与创建自己的聚合函数['CREATE AGGREGATE'(http://msdn.microsoft.com/en-us/library/ms182741.aspx),并使用所提供的[数学函数T-SQL](http://msdn.microsoft.com/en-us/library/ms177516.aspx)? – stakx

+1

我刚刚确认,你不能(也不应该)一个SQL CLR函数中产卵多线程。 – VVS

1

只是一个猜测,但如果你的“真实”问题是你需要经常运行扫描每列整个表做SUM()一个缓慢的查询,那么最快和最简单的方式来实现这一目标是一个持久的聚合视图。它基本上在INSERT/DELETE/UPDATE上产生SUM()开销,但SELECT速度是即时的。

基本上,你作出这样一个观点:

CREATE VIEW MyView WITH SCHEMABINDING AS 
SELECT SUM(col1) AS SumCol1, SUM(col2) AS SumCol2, ... 
FROM dbo.YourTable 
GO 
CREATE UNIQUE CLUSTERED INDEX idx_MyView ON MyView(SumCol1,SumCol2)