none
请教各位大牛,编码执行sql的性能差异 RRS feed

  • 问题

  • 您好:

        有以下两个方法:

        方法一:
    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);
        }
    }

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

     

    2010年11月25日 12:44

答案

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

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

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

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

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

全部回复

  • 因为语句没有变化,所以sql端的是一样的.

    接下来就看从sqlserver传输到客户端的时间了,时候有网络上的瓶颈,或者客户端接收所消耗的时间。

    还有就是客户端是否有足够的内存去容纳两个结果集,

    你可以用sql server profiler观察一下。我觉得两者没有区别

     


    有dba的职位吗(北京的),请联系我 stswordman#hotmail.com
    2010年11月25日 14:09
    版主
  • 语句没变化,您是指sql语句吗?那我把代码改成:

    方法三:

    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);
        }

    }

    sql语句也没有变化,方法三和一、二性能上有差异吗?谢谢!

    2010年11月25日 14:54
  • 我把类似的问题也发到ADO.NET论坛了。详情见http://social.microsoft.com/Forums/zh-CN/adonetzhchs/thread/05b9b135-bacd-4c6a-93b8-7fb610057a2a

    其中我谈到用Sql Server Profiler来跟踪。

    结果的确发现,方法一是在同一个批处理中执行,而方法二在不同的批处理中执行,最糟的方法三还触发了rpc:completed事件,其中执行了exec sp_reset_connection。

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

    希望各位大虾能顺着上面这个思路探讨,不希望问题朝着客户端是否能接收或者是网络问题的方向发展,谢谢!

    2010年11月27日 3:55
  • Did you compare duration of each method in profiler trace?

    2010年11月27日 4:01
  • Did you compare duration of each method in profiler trace?


    How? Pls. tell me more details. Thanks a lot!

    If I get the detail about duration, Would I know the internal work principle?

    It's important to me whether I can ignore the performance consumption that I mentioned above.

    2010年11月27日 6:51
  • 如果数据真的达到百万级别,不推荐使用上面的方法。

    建议使用datareader去读取数据内容。

    如果你非要讨论和事务相关的讨论,我建议你写2个代码比较。

    1.你插入10w条数据到数据库,不用任何事务,每次插入都执行一次。

    2.同样你插入10w条数据到数据库,不同的是,你每隔1000条使用事务提交一次。

    然后记录2次的耗时时间。

    看到这个结果后,我想你会对你上面的疑问有一个直观的认识。

     


    family as water
    2010年11月27日 19:15
  • Did you compare duration of each method in profiler trace?


    How? Pls. tell me more details. Thanks a lot!

    If I get the detail about duration, Would I know the internal work principle?

    It's important to me whether I can ignore the performance consumption that I mentioned above.

    Not sure what you are talking about, you should get all details in profiler trace.
    2010年11月27日 22:49
  • 如果数据真的达到百万级别,不推荐使用上面的方法。

    建议使用datareader去读取数据内容。

    如果你非要讨论和事务相关的讨论,我建议你写2个代码比较。

    1.你插入10w条数据到数据库,不用任何事务,每次插入都执行一次。

    2.同样你插入10w条数据到数据库,不同的是,你每隔1000条使用事务提交一次。

    然后记录2次的耗时时间。

    看到这个结果后,我想你会对你上面的疑问有一个直观的认识。

     


    family as water

    我根本就没有提到任何事务的字眼!!!也没有要讨论数据插入,请麻烦看清,另我取消百万级数据的假设。原意的话请见http://social.microsoft.com/Forums/zh-CN/adonetzhchs/thread/05b9b135-bacd-4c6a-93b8-7fb610057a2a 谢谢!
    2010年11月28日 2:51
  • Did you compare duration of each method in profiler trace?


    How? Pls. tell me more details. Thanks a lot!

    If I get the detail about duration, Would I know the internal work principle?

    It's important to me whether I can ignore the performance consumption that I mentioned above.

    Not sure what you are talking about, you should get all details in profiler trace.


    我的本意很简单就是想借助各位丰富的经验回答一个性能消耗问题,我想知道在代码中能否忽略一个性能消耗问题。

    既然提到性能消耗,我想我需要定一个基调,就是什么样的性能消耗能被忽略,什么样的性能消耗不能被忽略。那么我希望是低于“打开数据库连接的性能”。

    2010年11月28日 2:55
  • 对于sql server来说,没有大于0.1秒的性能差距
    想不想时已是想,不如不想都不想。
    2010年11月29日 2:50
    版主
  • 对于sql server来说,没有大于0.1秒的性能差距
    想不想时已是想,不如不想都不想。

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

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

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

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

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