开发者社区> 问答> 正文

【阿里云产品公测】利用PTS服务优化网站数据库读写性能

           写这个帖子主要也是因为在用PTS测试网站的时候,手动访问网站进入报错页面,主要原因是数据库连接对象存在问题,导致并发多的时候产生故障,于是简单分析了一下数据库读写的性能优化以及利用PTS的测试结果,整理出来和大家分享一下,顺便参加一下这个活动。

         几乎所有的网站都需要数据库来存储网站中的相关信息,因此在网站应用与数据库的交互过程中,数据库数据读取的性能对网站整体的性能是至关重要的。
         通常我们在网站编写之初不会考虑数据库的读写效率,主要是因为这时候网站建设的重点并不在数据库读写性能上,而是在数据库读写处理得正确性上,因此很多网站的开发人员一开始并没有重视这个问题,包括我也一样,在之前网站开发中,每次需要读写的操作,利用定义好的数据库连接类new一个对象,然后执行操作即可,至于连接对象的连接池,交给系统自己去维护,并没有过多的干预。
         比如常见的的一种方式如下:

            SQLServerCMD cmd = newSQLServerCMD();
           // new SQLServerCMD()时,自动从连接池中获取一个可用连接,再使用Open打开连接,使用完毕后Close

            String value = cmd.QueryValue("selectuser_name from User_Table where user_id=123");


         稍微好一点的开发者估计会将数据库与网站分离,然后在数据库上建立一些存储过程来调整开发代码以及数据读写性能,上述代码估计会变成如下形式:
          SQLServerCMD cmd = newSQLServerCMD();

           String value = cmd.QueryValue("GetUserName123");


          从个人的开发经验来说,如果网站访问量不大的话,可以不用先进行数据库分离,但事存储过程强烈推荐,不然以后代码维护会很麻烦,至于后期用户增多,数据库分离也就是修改一下配置文件,复制一下数据库中数据而已,操作相对简单。
         继续讨论数据库读写对程序的影响。
         比如说两个记录非常大的表User_Table, User_Log(包含用户id字段),比如下列测试代码,均可以根据日志表的用户id读取用户姓名,但在网站编写的时候,如果是你,你会选择哪种方式编码呢?
方法一:两个表进行自然连接后条件查询:
SQLServerCMD cmd = newSQLServerCMD();

SqlDataReaderdr = cmd.Query("select user_name from User_Table,User_Log where user_id=log_user_idand user_id=123")

方法二:两个表没有进行自然连接,采取嵌套的方式进行查询:
           SQLServerCMDcmd = new SQLServerCMD();
           SQLServerCMDcmd2 = new SQLServerCMD();
            SqlDataReader dr =cmd.Query("GetLog 12"); //获取第12条记录的数据
            string username="-";
            using(dr)
            {
                if(dr.Read())
                {
                    string  id =dr["user_id"].ToString().Trim();
                    username = cmd2.Get_Value("selectuser_name from User_Table where user_id=" + id);
                }
            }
        

         对于数据记录比较大的表,应尽量避免带有笛卡尔操作的数据库查询,不然性能绝对大打折扣;对于嵌套的查询,需要多个数据库连接对象,进行多次查询,对于操作次数频繁的操作,这样无疑又多了很多开销。因此选择哪种方式还应根据实际情况进行具体分析,这也就是为什么网站从初期开始,性能维护都是一个老生常谈的问题,对于不同的用户量,对于不同数据级别的性能优化,方法都不一样,不可能用一种方式适用所有场景。
       对于大型的网站,估计网站都会有自己的数据库连接池,而且其中的架构也是整个网站的核心之一。为了对比数据库连接池对性能的提升,我自定义了一个最简单的数据库连接池,其中主要的属性为:

privatestatic List<SQLServerCMD> pool = new List<SQLServerCMD>();          //连接对象集合
privatestatic Dictionary<int, int> used = new Dictionary<int, int>();                 //连接对象使用次数
privatestatic int index = 0;                                                                          //轮询连接标识
privatestatic int MaxCount = 20;                                                                 //连接池连接对象数


         其中的原理就是网站启动时初始化20个可用连接,然后利用一个轮训标记index选择下一个作为连接对象,并记录每个连接对象的使用情况,定义的这个连接池是静态类,同时定义一个静态方法获取连接,在需要数据库读写的时候调用即可,如:

SQLServerCMDcmd = SqlConnectionPool.GetSqlConnection();
Stringvalue = cmd.QueryValue("GetUserName 123");

        

         其中主要就是避免了在newSQLServerCMD时不断的调用Open,Close的耗时操作。
         建立了两个测试页面,均包含读取数据库内容,选择指定记录进行更新,具体内容如下:
普通连接

SQLServerCMD cmd = newSQLServerCMD();
SQLServerCMD cmd2 = newSQLServerCMD();
SqlDataReader dr =cmd.Query("select * from User_Table");
string id ="123";
string username ="-";
using (dr)
{
     if (dr.Read())
     {
         id =dr["user_id"].ToString().Trim();
         username =cmd2.Get_Value("select user_name from User_Table where user_id=" +id);
     }
}
cmd.Update("updateUser_Table set user_name='LT' where user_id='" + id + "'");
cmd.CloseConnection();
cmd2.CloseConnection();
自定义连接池连接


SQLServerCMD cmd =SqlConnectionPool.GetSqlConnection();        //连接的初始化方式不同
SQLServerCMD cmd2 =SqlConnectionPool.GetSqlConnection();
SqlDataReader dr =cmd.Query("select * from User_Table");
string id="123";
using(dr)
{
     if(dr.Read())
    {
         id =dr["user_id"].ToString().Trim();
         string username =cmd2.Get_Value("select user_name from User_Table where user_id=" +id);
    }
}
cmd.Update("updateUser_Table set user_name='LT' where user_id='" + id+"'");


对于单个包含数据读取的页面,利用阿里云的PTS测试结果如下:
一、建立测试脚本,主要添加事务,设置请求链接,如:


普通测试脚本


带连接池测试脚本

二、快速启动,测试结果

       可以看到TPS的性能指数从2.95提高到了42.29,这应该算是一个很大的性能提高了。由于仅仅是测试,对于网站的性能,主要还是以TPS为主,所以并没有增加绑定ECS,RDS的性能,因此后两个指数均为0。
        能力有限,以上分析可能存有不足,敬请纠正。



展开
收起
千鸟 2014-10-09 01:53:45 13462 0
6 条回答
写回答
取消 提交回答
  • Re【阿里云产品公测】利用PTS服务优化网站数据库读写性能
    学习下
    2014-10-17 22:47:01
    赞同 展开评论 打赏
  • Re【阿里云产品公测】利用PTS服务优化网站数据库读写性能
    网站建设的重点并不在数据库读写性能上,而是在数据库读写处理得正确性上
    2014-10-13 18:53:11
    赞同 展开评论 打赏
  • 不错,数据库性能分析的典型案例
    2014-10-13 18:38:05
    赞同 展开评论 打赏
  • LT是个伪程序员
    回 1楼(qiujin2012) 的帖子
    已投

    -------------------------

    回 2楼(啊里新人) 的帖子
    对于数据库的读写性能还是很重要的。

    -------------------------

    回 5楼(童战) 的帖子
    谢谢支持~~~

    -------------------------

    回 6楼(皇族) 的帖子
    的确这样,正确性是基础,同时读写性能也很关键
    2014-10-10 06:52:00
    赞同 展开评论 打赏
  • 这个还没有试过,不过我的应用貌似不适合这个测试
    2014-10-09 15:52:26
    赞同 展开评论 打赏
  • 支持他,就给他投票,猛戳:
    http://bbs.aliyun.com/read/178799.html
    2014-10-09 12:00:44
    赞同 展开评论 打赏
滑动查看更多
问答排行榜
最热
最新

相关电子书

更多
DTCC 2022大会集锦《云原生一站式数据库技术与实践》 立即下载
阿里云瑶池数据库精要2022版 立即下载
2022 DTCC-阿里云一站式数据库上云最佳实践 立即下载