为了账号安全,请及时绑定邮箱和手机立即绑定

如何进行性能优化

标签:
SQL Server

       最近有客户反馈系统导入EXECL进行数据处理超时了,我当时的第一反应,不可能啊我明明是做过性能优化的啊,怎么还会超时呢,这是要有多少条数据才可能发生啊!于是找客户要来了EXECL,发现有7500多条数据,备份完客户数据库进行代码调试找出性能差的地方。都是一些平时老生常谈的东西,可是又是很容易忽略的地方,这里面就只谈两个点,使用String还是StringBuilder,校验数据正确性是在循环里面一条一条的使用SQL取数呢,还是一次性取出来在代码里面进行校验!下面将用实际数据结合图表,给出准确的答案。

阅读目录

  • String和StringBuilder性能差异比较

  • 循环取数还是一次性取数?

  • 示例下载及总结

回到顶部

String和StringBuilder性能差异比较

   String和StringBuilder的差别这里就不提了,学习和工作中常常会听到拼接字符串要使用StringBuilder对象速度很快,但是可能你只是知道这个知识,实际开发工作中有关注过这一点吗?我也是当客户反馈之后自己跟踪用实际效果才学会这个知识,后续开发中也会铭记这一点!下面的实际数据或许能说明些问题。

      分别调用了这个函数,   循环次数为 1,5,15,200,500,1500,2500,5500,8500,20000  后面数据可以下载最后的DEMO实验一下,String在这时已经是慢到不行了。为了保证数据的准确性,这里每个量级的数据都取了十次值,然后求出平均值。

复制代码

 <summary>         对比String和StringBuilder拼接字符串的速度         每种量级测试,取十次时间平均值        </summary>        </param>         Total){            List<();            )            {                list.Add(Guid.NewGuid().ToString());            }            ;            总执行时间 ms            ;            String拼接             String.Empty;            )            {                DateTime dtBegin = DateTime.Now;                 list)                {                    strGUID = strGUID + temp + ;                }                DateTime dtEnd = DateTime.Now;                TotalMilliseconds += (dtEnd - dtBegin).TotalMilliseconds;                iTest--;            }            Console.WriteLine();            StringBuilder拼接            StringBuilder sb =  StringBuilder();            iTest = ;            TotalMilliseconds = ;            )            {                DateTime dtBegin = DateTime.Now;                 list)                {                    sb.AppendFormat(, temp);                }                DateTime dtEnd = DateTime.Now;                TotalMilliseconds += (dtEnd - dtBegin).TotalMilliseconds;                iTest--;            }            Console.WriteLine();        }

复制代码

执行结果如下图:

  

 绘制成曲线图:

   

   从上图可直观看出来,String拼接是呈几何形递增的,而StringBuilder呈线性的,递增趋势很慢。在循环次数多的情况下使用哪种拼接,相信大家都清楚了吧!在7500的数量时,可以节省整整4s的时间,性能是不是提升很多呢?

回到顶部

循环取数还是一次性取数?

  背景:EXECL中有7500行学生信息数据,要把这些数据导入到学生表(p_Student)里面,但是要保证学生编号(StudentNo)唯一,不唯一导入的时候需要给出提示信息。这就需要在后台代码里面读取EXECL里面的学生信息然后校验学生编码在数据库中是否存在,当然EXECL中填写的学生编号也要校验唯一。下面就来模拟这个过程,以两种方式比较性能。、

  首先创建学生信息表,插入7500条数据,下面是SQL脚本,学生编号这里插入的是newid,实际情况不会是这样的,这里只是会了保证唯一,但是又是无序的,尽可能模拟真实情形。

复制代码

*/GO))BEGIN*/*/*/(       ,    )   ,    )   ,    )   ,    )   ,    (StudentGUID))     sysname()''''''ENDGO插入7500条模拟数据INT p_Student0BEGIN    INT    7500    0    BEGIN         dbo.p_Student                ( StudentGUID ,                  Name ,                  Major ,                  Sex ,                  StudentNo                )         StudentGUID - uniqueidentifier                   Name - varchar(40)                   Major - varchar(100)                   Sex - varchar(8)                   StudentNo - varchar(100)                )        1    ENDENDGO

复制代码

      基础信息准备好以后,进入后台代码

复制代码

 >         统计循环校验和一次性校验性能差异        >         Total)        {            这里模拟学生编号            List();            )            {                listStudetNo.(Guid.NewGuid().ToString());            }            using (SqlConnection con  new SqlConnection(SqlCon))            {                con.();                string strSQL <span ;                SqlCommand cmd  con.CreateCommand();                循环校验                ;                )                {                    foreach (string studentNo  listStudetNo)                    {                        .Now;                        cmd.CommandText  String.Format(strSQL, studentNo);                        )cmd.ExecuteScalar();                        )                        {                            Console.WriteLine("{<span , studentNo);                            ;                        }                        .Now;                        TotalMilliseconds  dtBegin).TotalMilliseconds;                    }                }                Console.WriteLine("循环校验{);                一次性校验                TotalMilliseconds ;                strSQL <span ;                )                {                    .Now;                    StringBuilder sb  new StringBuilder();                    foreach (string studentNo  listStudetNo)                    {                        sb.AppendFormat("{<span , studentNo);                    }                    cmd.CommandText <span ));                    string no  (string)cmd.ExecuteScalar();                     (!string.IsNullOrEmpty(no))                    {                        Console.WriteLine("{<span , no);                        ;                    }                    .Now;                    TotalMilliseconds  dtBegin).TotalMilliseconds;                }                Console.WriteLine("一次性校验{);            }        }

复制代码

    从上图可直观看出来,循环校验和一次性校验都是线性递增的,一次性校验速度差不多比循环的快一倍左右。

回到顶部

示例下载及总结

         示例sql,示例代码DEMO

         其实性能优化不仅仅只有这么一点,需要在日常工作中总结,这次性能优化还有一点也令我惊叹,有一条SQL未优化之前执行需要20s左右,给表添加了索引,速度刷的一下变成0s了,最终性能问题圆满解决了。

        性能优化思想:

        1:大量字符串拼接请采用StringBuilder

        2:千万不要在大量循环里面循环查SQL,考虑是否能用一次性查询代替,或者一次性把数据查询出来在代码里面进行逻辑判断

        3:SQL执行速度慢,可以采用执行计划看看是否表缺少索引。

      好了本篇到这里就要结束了,如果觉得对你有益,记住点赞哦!

  

   相关阅读:附加没有日志文件的数据库方法  删除数据库日志文件的方法  数据字典生成工具系列文章

如果,您认为阅读这篇博客让您有些收获,不妨点击一下右下角的【推荐】按钮。
如果,您希望更容易地发现我的新博客,不妨点击一下绿色通道的【关注我】。

如果,想给予我更多的鼓励,求打

因为,我的写作热情也离不开您的肯定支持。

点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
移动开发工程师
手记
粉丝
8
获赞与收藏
24

关注作者,订阅最新文章

阅读免费教程

  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消