2011-08-10 40 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)