none
以下3个方法的性能比较,谢谢! RRS feed

  • 问题

  • 您好:

        有以下3个方法:

        方法一:
    private static void SelectRows(DataSet dataset,
        string connectionString)
    {
        string queryString =
            "SELECT OrderID, CustomerID FROM dbo.Orders; ";
        queryString +=
            " SELECT OrderID, CustomerID FROM dbo.Orders2;";

        using (SqlConnection connection =
            new SqlConnection(connectionString))
        {
            SqlDataAdapter adapter = new SqlDataAdapter();
            adapter.SelectCommand = new SqlCommand(
                queryString, connection);
            adapter.Fill(dataset);
        }
    }

    方法二:

    private static void SelectRows(
        string connectionString)
    {
        string queryString =
            "SELECT OrderID, CustomerID FROM dbo.Orders; ";
        string queryString2 =
            " SELECT OrderID, CustomerID FROM dbo.Orders2;";
       
        using (SqlConnection connection =
            new SqlConnection(connectionString))
        {
            SqlDataAdapter adapter = new SqlDataAdapter();
            adapter.SelectCommand = new SqlCommand(
                queryString, connection);
            DataSet dataset = new DataSet();
            adapter.Fill(dataset);
           
            DataSet dataset2 = new DataSet();
            adapter.SelectCommand = new SqlCommand(
                queryString2, connection);
            adapter.Fill(dataset2);
        }
    }

    方法三:

    private static void SelectRows(
        string connectionString)
    {
        string queryString =
            "SELECT OrderID, CustomerID FROM dbo.Orders; ";
        string queryString2 =
            " SELECT OrderID, CustomerID FROM dbo.Orders2;";
       
        using (SqlConnection connection =
            new SqlConnection(connectionString))
        {
            SqlDataAdapter adapter = new SqlDataAdapter();
            adapter.SelectCommand = new SqlCommand(
                queryString, connection);
            DataSet dataset = new DataSet();
            adapter.Fill(dataset);
        }

       using (SqlConnection connection2 =
            new SqlConnection(connectionString))
        {
           SqlDataAdapter adapter2 = new SqlDataAdapter();

            DataSet dataset2 = new DataSet();
            adapter2.SelectCommand = new SqlCommand(
                queryString2, connection2);
            adapter2.Fill(dataset2);
        }

    }

    如果表Orders和Orders2都有百万条数据。那么请教方法一、二和三的性能差别大吗?
    我的理解是因为方法一和二因同在一个SqlConnection内执行,性能差别应该不大,即忽略adapter的调用时间,而方法三性能差些对吗?能有什么方法证明?

    2010年11月26日 5:47

答案

  • 经过几天的摸索,查到Adapter的批处理处理很接近我的需求。该功能由UpdateBatchSize提供。

    当我跟踪到底层实现时发现调用了SqlCommand的AddBatchCommand方法,可惜该方法为internal。可见微软不愿批处理功能被随意使用。还需要深入研究AddBatchCommand相信会有收获。

    实际上我提的问题就是要减少客户端和服务器端的往返。只不过再深入了一些。

    可能和大家的信息不对等,要么是我没提问好,要么是大家没理解,只能先给各位投上一票,并在此结贴,谢谢大家!

    • 已标记为答案 Jiyuan 2010年11月29日 7:15
    2010年11月29日 7:14

全部回复

  • 不管是哪一種,底層都是 DataReader,差異並不會太大。
    所以重點應該是在減少查詢量,而不是一次撈回所有資料,尤其是資料數很多時。

    要證明很簡單,就在查詢前後各取一個 DateTime.Now(開始是 dateStart,結果是 dateEnd),然後用 dateEnd - dateStart 取得一個 TimeSpan,再由它取得執行所花的時間即可。


    小朱的技術隨手寫:http://www.dotblogs.com.tw/regionbbs/
    目前籌建雲端運算學堂 (studyazure.com) 中...
    2010年11月26日 10:44
  • 可以用 datetime.now.ticks 来取时间,方法执行前执行后个取值,之后取差,来获取执行时间
    2010年11月26日 13:25
  • 首先谢谢两位的答复,先投上一票。

    看来我的百万数据的假设夺了大家的眼球,我想应该把这个假设去掉。我的本意是想深入讨论这3个方法的细节。

    采用时间的截取只能大致上给个感觉,我不认为这个是证明。再者对于大量数据的访问,用时间截取方法,我认为是没有太大的意义。

    很明显,第3个方法因为跨越不同的connection,肯定是最慢的,因为connection的打开是昂贵的(事实也如此,下面我会提到)。我最想知道的是方法一和二的差异在哪。

    忽然我想起用Sql Server Profiler来跟踪,结果的确发现,方法一是在同一个批处理中执行,而方法二在不同的批处理中执行,最糟的方法三还触发了rpc:completed事件,其中执行了exec sp_reset_connection。

    但我现在还分不清,在同一批处理和不同批处理间执行的性能差异到底有多大,是不是可以忽略。(我这里的忽略标准指的是类似打开关闭connection的性能消耗级别。换句话说只要不同批处理间的性能消耗不会像打开关闭connection那么严重,我就认为可以忽略)。

    希望各位大虾能顺着上面这个思路探讨,不希望问题朝着是否一次获取所有数据的方向,谢谢!

    2010年11月27日 3:50
  • 经过几天的摸索,查到Adapter的批处理处理很接近我的需求。该功能由UpdateBatchSize提供。

    当我跟踪到底层实现时发现调用了SqlCommand的AddBatchCommand方法,可惜该方法为internal。可见微软不愿批处理功能被随意使用。还需要深入研究AddBatchCommand相信会有收获。

    实际上我提的问题就是要减少客户端和服务器端的往返。只不过再深入了一些。

    可能和大家的信息不对等,要么是我没提问好,要么是大家没理解,只能先给各位投上一票,并在此结贴,谢谢大家!

    • 已标记为答案 Jiyuan 2010年11月29日 7:15
    2010年11月29日 7:14