簡體   English   中英

CLR sql server性能

[英]CLR sql server performance

我們在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函數沒有選項,因為沒有錯誤提升。

PS。 我們正在使用SQL 2008R2。

通過創建新連接或為每個函數調用分配內存的開銷。 所以解決方案可能是連接/內存池。

在C#方面,您不必擔心。 你沒有分配內存(當然你在你的函數中分配你需要的字符串和東西,沒有你可以集中/重用的東西)。 連接也不是你必須擔心的事情。

除性能外,這種方法很好。

你的代碼正在做一些令人難以置信的事情......特別......慢 :拋出異常而不是執行檢查。 異常是一個擴展操作 ,應用於處理特殊情況(僅100/200個記錄具有null或無效值,這會減慢1,000,000條記錄的查詢速度)。 錯誤輸入格式或null數據庫中的列值......也不例外(這種編程風格-異常而不是檢查-是允許的 ,即使是在像Python語言鼓勵我一般避免它在C#中確定。這在性能是一個問題的地方是不合適的)。

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

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

請注意:對於null輸入或僅由空格組成的字符串, String.IsNullOrWhiteSpace(input)將返回true (替換Trim()NullReferenceException東西)。 其他所有內容(輸入文本的FormatException不是整數或具有OverflowException的太大數字)由Int16.TryParse()處理。 有效輸入的代碼較短( 略快 ),而無效輸入的代碼則 許多倍

我將這個問題作為一個單獨的答案而不是對@Adriano的回答進行評論,以便不太可能被錯過(因為不是每個人都閱讀所有評論)。


除了按照@Adriano的建議更改方法之外 ,您應該使用System.Data.SqlTypes命名空間中的相應數據類型來獲取所有輸入/輸出參數和返回值。 使用它們有一些重要的區別和好處,例如它們都具有.IsNull屬性。 完整的差異列表是放在這里的太多信息,但我在下面的文章中做了記錄: SQLCLR的階梯級別5:開發(在SQL Server中使用.NET)

調整@Adriano的代碼以使用正確的類型將為您提供以下內容:

public static SqlBoolean check_smallint(SqlString input)
{
    if (input.IsNull)
        return true;

    if (input.Value.Trim() == String.Empty)
        return true;

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM