• 滥用存储过程的思考


    存储过程在数据库本地编译本地运行显然是提高数据库访问效率的首选,但实际中有不少朋友误解了只要是存储过程就是高性能的表现,认为只要是存储过程实现的逻辑操作就肯定比客户端操作数据库效率高;但他们却忘记重要的一点就是效率很大程度是依赖于具体实现的代码。接下来做个简单的测试证明这一点。

    数据分页功能是经常讨论的话题,在很多人眼中在dotNet的Client端进行数据分页是非常低效,根本不可能和存储过程匹敌;即使很糟糕的存储过程代码也会比dotNet的Client要快。为了证实这一点于是编写了一个简单的dotNet分页代码和传统的MSSQL用临表进行分页的存储进行了比较。

    测试描述:

    对MSSQL NorthWind数据的Orders表进行分页操作,分页的总记录数830条。对相关分页代码进行10次调用,每次调用分别执行1页到5页的数据集获取。

    dotNet分页代码:

    const string getindex = "select orderid from orders";
    const string getrecord = "select * from orders where orderid in ({0})";
    
    static System.Data.DataTable GetDataSQL(int page)
    {
        System.Text.StringBuilder index = new StringBuilder();
        SqlDataAdapter da;
        System.Data.DataSet ds = new System.Data.DataSet();
        SqlCommand cmd = new SqlCommand();
        int start, end;
        start = 10 * page;
        end = start + 10;
        int cur = 0;
        using (SqlConnection conn = new SqlConnection("data source=.;initial catalog=northwind;user id=sa;pwd=;"))
        {
            cmd.Connection = conn;
            cmd.CommandText = getindex;
            conn.Open();
            using (SqlDataReader reader = cmd.ExecuteReader())
            {
                while (reader.Read())
                {
                    if (cur >= start && cur < end)
                    {
                        if (index.Length > 0)
                        {
                            index.Append(",");
                        }
                        index.Append("'" + reader[0].ToString() + "'");
                    }
                    if (cur > end)
                    {
                        cmd.Cancel();
                        break;
                    }
                    cur++;
                }
            }
            cmd.CommandText = string.Format(getrecord, index.ToString());
            da = new SqlDataAdapter(cmd);
            da.Fill(ds, "table1");
            return ds.Tables[0];
        }
    }

    存储过程分页代码:

    CREATE PROC testList
    (
    @PageIndex int,
    @PageSize int
    )
    as
    DECLARE @PageLowerBound int
    DECLARE @PageUpperBound int
    SET @PageLowerBound = @PageSize * @PageIndex
    SET @PageUpperBound = @PageLowerBound + @PageSize + 1
    
    Create Table #IDs
    (
        TempID int IDENTITY,
        orderid int not null
    )
    Insert into #IDs(orderid) select orderid from orders
    SELECT orders.*
    FROM orders
    INNER JOIN #IDS ON (orders .[orderid] = #IDS.orderid)
    WHERE #IDS.TempID > @PageLowerBound
    AND #IDS.TempID < @PageUpperBound
    GO
    static System.Data.DataTable GetDataSP(int page)
    {
        SqlDataAdapter da;
        System.Data.DataSet ds = new System.Data.DataSet();
        SqlCommand cmd = new SqlCommand();
        using (SqlConnection conn = new SqlConnection("data source=.;initial catalog=northwind;user id=sa;pwd=;"))
        {
            cmd.Connection = conn;
            cmd.CommandText = "testList";
            cmd.CommandType = System.Data.CommandType.StoredProcedure;
            cmd.Parameters.Add("@PageIndex", page);
            cmd.Parameters.Add("@PageSize", 10);
            conn.Open();
            da = new SqlDataAdapter(cmd);
            da.Fill(ds, "table1");
            return ds.Tables[0];
        }
    }

    测试结果:

    存储过程分页:74毫秒

    dotNet分页:64毫秒

    存储过程分页:21毫秒

    dotNet分页:10毫秒

    存储过程分页:1023毫秒

    dotNet分页:11毫秒

    存储过程分页:20毫秒

    dotNet分页:11毫秒

    存储过程分页:22毫秒

    dotNet分页:12毫秒

    存储过程分页:1031毫秒

    dotNet分页:10毫秒

    存储过程分页:20毫秒

    dotNet分页:10毫秒

    存储过程分页:21毫秒

    dotNet分页:10毫秒

    存储过程分页:20毫秒

    dotNet分页:10毫秒

    存储过程分页:21毫秒

    dotNet分页:10毫秒

    是什么情况导致效率相差这么远,而效率低下的却是存储过程而并不是dotNet代码。相信大家看一下存储过程的处理应该知道原因所在.

  • 相关阅读:
    《JavaScript高级程序设计》学习笔记12篇
    JS学习笔记12_优化
    JS学习笔记11_高级技巧
    JS学习笔记10_Ajax
    JS学习笔记9_JSON
    JS学习笔记8_错误处理
    为什么要在列表组件里写 Key ?
    var、let 和 const 的区别以及暂时性死区
    小程序性能优化要点
    Node require() 加载规则
  • 原文地址:https://www.cnblogs.com/masahiro/p/10131594.html
Copyright © 2020-2023  润新知