首页 > 其他分享 >常规代码性能优化的总结

常规代码性能优化的总结

时间:2024-02-19 15:33:47浏览次数:22  
标签:transaction 代码 常规 DataRow command 使用 优化 数据库 row

  今天同事发开中遇到了一个代码性能优化的问题,原本需求是:从一个数据库中查询某个表数据,存放到datatable中,然后遍历datatable,看这些数据在另一个数据库的表中是否存在,存在的话就要更新,不存在就要插入。

  就这个需求本身来说很简单,但是随着数据量的增大,之前通过循环遍历的方式就出现了性能问题。我在思索片刻后,给出的建议是分页查询和利用事务批量提交。

1.利用数据库事务批量提交

1 using (SqlTransaction transaction = targetConnection.BeginTransaction()) 2 { 3 foreach (DataRow row in dataTable.Rows) 4 { 5 if (CheckIfDataExists(targetConnection, transaction, row)) 6 { 7 UpdateData(targetConnection, transaction, row); 8 } 9 else 10 { 11 InsertData(targetConnection, transaction, row); 12 } 13 } 14 15 transaction.Commit(); 16 } 17 } 18 19 //下面两个方法都还可以优化,需要接收批量sql语句,所以可以修改成list<SqlCommand>,然后遍历执行,此处能说明问题即可 20 private void UpdateData(SqlConnection connection, SqlTransaction transaction, DataRow row) 21 { 22 using (SqlCommand command = new SqlCommand("UPDATE YourTable SET YourUpdateStatement WHERE YourCondition", connection, transaction)) 23 { 24 // Add parameters to your command here, based on your update statement and condition 25 // command.Parameters.AddWithValue("@ParameterName", row["ColumnName"]); 26 27 command.ExecuteNonQuery(); 28 } 29 } 30 31 private void InsertData(SqlConnection connection, SqlTransaction transaction, DataRow row) 32 { 33 using (SqlCommand command = new SqlCommand("INSERT INTO YourTable (YourColumns) VALUES (YourValues)", connection, transaction)) 34 { 35 // Add parameters to your command here, based on your columns and values 36 // command.Parameters.AddWithValue("@ParameterName", row["ColumnName"]); 37 38 command.ExecuteNonQuery(); 39 } 40 }

  看到这里的时候,大家可以考虑下,以上方案还有什么优化的地方吗?

  当然是有的,如果数据量持续增大,datatable这样直接加载到内存的方式恐怕会成为性能问题点吧,我们得考虑怎么优化才能避免将大数据一次性加载到内存,大部分同学第一个想到的就是分页,这个方案当然是没有错,但是还不够高级,给大家提示一个关键字“yield”,或许从聪明的你已经悟到了,接着往下看。

2.流式处理法

  什么是流式处理法呢

  流式处理是一种处理数据的方式,它允许你在数据到达时立即处理,而不是等待所有数据都到达后再处理。这种方式特别适合处理大量数据,因为它不需要一次性加载所有数据到内存中。 在C#中,你可以使用yield return关键字来创建一个返回IEnumerable<T>的方法,这个方法可以在每次迭代时返回一个元素,而不是一次性返回所有元素。这就是一种流式处理的实现方式。 举个例子: 1 private IEnumerable<DataRow> GetDataFromSource() 2 { 3 using (SqlConnection sourceConnection = new SqlConnection(sourceConnectionString)) 4 { 5 sourceConnection.Open(); 6 7 using (SqlCommand command = new SqlCommand("SELECT * FROM YourTable", sourceConnection)) 8 { 9 using (SqlDataReader reader = command.ExecuteReader()) 10 { 11 DataTable dataTable = new DataTable(); 12 13 while (reader.Read()) 14 { 15 dataTable.LoadDataRow(reader.GetValues(), LoadOption.Upsert); 16 DataRow row = dataTable.Rows[dataTable.Rows.Count - 1]; 17 yield return row; 18 dataTable.Clear(); 19 } 20 } 21 } 22 }   在这个示例中,GetDataFromSource方法每次迭代时返回一个DataRow,而不是一次性返回所有DataRow。这样,你就可以在每次迭代时处理一个DataRow ,而不需要一次性加载所有数据到内存中。但是如果你的数据处理需要跨行操作,你可能需要使用其他的方法了,这个就不适用。   扫盲:yield一次只返回一个难道就不会多次访问数据库了吗?   在这个示例中,yield return并不会导致多次访问数据库。实际上,数据库查询只执行一次,然后使用SqlDataReader逐行读取结果。yield return只是在每次迭代时返回一个DataRow,而不是一次性返回所有DataRow。 当你在foreach循环中迭代GetDataFromSource()方法时,每次迭代都会从上次停止的地方继续,直到SqlDataReader读取完所有行。这意味着,虽然你每次只处理一个DataRow,但数据库查询只执行一次。  

常规优化手段

  既然已经看到这里了,我们可以继续再考虑下关于性能优化,我们还能从哪些方面着手呢?

1. 代码层面:

- 使用更高效的数据结构和算法。 - 使用缓存避免多次数据库交互 - 减少不必要的计算和内存分配。 - 利用并行和异步编程提高性能。 - 使用性能分析工具定位和优化瓶颈。  

2. Web API方面:

- 使用HTTP缓存减少不必要的请求。 - 使用Gzip或Brotli压缩减少响应大小。 - 使用分页、排序和过滤减少返回的数据量。 - 使用GraphQL或OData让客户端可以指定需要的数据。  

3. 数据库方面:

- 使用索引加速查询。 - 使用批量操作减少数据库交互次数。 - 使用读写分离和数据库分片提高并发性能。 - 使用缓存减少数据库访问。  

4. Nginx方面:

- 使用反向代理和负载均衡提高并发性能。 - 使用缓存减少后端服务器的负载。 - 使用Gzip压缩减少网络传输量。  

5. CDN方面:

- 使用CDN加速静态资源的访问。 - 使用边缘计算将计算任务靠近用户。  

6. 微服务方面:

- 使用服务间的异步通信减少等待时间。 - 使用服务的横向扩展提高并发性能。 - 使用服务的分区设计提高可扩展性。   - 根据业务需求,考虑使用redis、rabbitmq、mangoDB等等中间件  

7. 其他方面:

- 使用自动扩缩容的云服务应对流量波动。 - 使用性能监控和日志分析工具定位性能问题。 - 使用容器和Kubernetes等技术提高部署和运行的效率。 - 使用链路追踪SkyWorking具体查看哪条链路的性能瓶颈     性能优化本身就是一个非常庞大的话题,需要具体问题具体分析,总的来说是,平常能用到的就是以上总结的这些点。技术永远是为业务服务的,根据不同的业务选择合适的技术是高级开发者必须要考虑的问题。今天分享就这些了,关于性能优化大家还有那些经验可以评论区分享!

 

2024-02-19 15:27:45【出处】:https://www.cnblogs.com/Mr-Worlf/p/18020445

=======================================================================================

标签:transaction,代码,常规,DataRow,command,使用,优化,数据库,row
From: https://www.cnblogs.com/mq0036/p/18021229

相关文章

  • 晚上调代码时写对拍程序之——为了不手写平衡树而乱搞的可支持随机访问、快速插入、快
    前言由于需要一个可支持随机访问、快速插入、快速删除的数据结构,但是我除了平衡树实在是想不到别的东西了,于是就乱搞出了一个这样的东西——abstract数组。但是,这玩意好像码量和平衡树差不多......不过!我认为她还是有优点的:相比起平衡树,她应该更不容易出锅?总之,不管怎么样,还是......
  • 代码随想录算法训练营第二十二天 | 450.删除二叉搜索树中的节点, 701.二叉搜索树中的
     450.删除二叉搜索树中的节点 已解答中等 相关标签相关企业 给定一个二叉搜索树的根节点 root 和一个值 key,删除二叉搜索树中的 key 对应的节点,并保证二叉搜索树的性质不变。返回二叉搜索树(有可能被更新)的根节点的引用。一般来说,删除节点......
  • day29 回溯算法part5 代码随想录算法训练营 46. 全排列
    题目:46.全排列我的感悟:看不下去视频,可以先看文字讲解。看答案。带着疑问去看视频,效果会更好。加油!理解难点:排列,不用start_index了借助used=1来过滤掉[1,1,1]这种情况。如果不加ifused[i]==1,continue就会出现重复的。如下图: 代码示例:classSolution:d......
  • css样式相关代码记录
    element样式穿透:::v-deepposition属性值有static、relative、absolute、fixed、sticky。static:该关键字指定元素使用正常的布局行为,即元素在文档常规流中当前的布局位置。relative:该关键字下,元素先放置在未添加定位时的位置,再在不改变页面布局的前提下调整元素位置(因此会......
  • 关于代码性能优化的总结
    今天同事发开中遇到了一个代码性能优化的问题,原本需求是:从一个数据库中查询某个表数据,存放到datatable中,然后遍历datatable,看这些数据在另一个数据库的表中是否存在,存在的话就要更新,不存在就要插入。就这个需求本身来说很简单,但是随着数据量的增大,之前通过循环遍历的方式......
  • JimuReport积木报表 v1.7.0 变革版本发布,低代码报表设计工具
    项目介绍一款免费的数据可视化报表,含报表和大屏设计,像搭建积木一样在线设计报表!功能涵盖,数据报表、打印设计、图表报表、大屏设计等!Web版报表设计器,类似于excel操作风格,通过拖拽完成报表设计。秉承“简单、易用、专业”的产品理念,极大的降低报表开发难度、缩短开发周期、节......
  • Netlify、Vercel 和 Digital Ocean代码托管平台介绍
    Netlify、Vercel和DigitalOcean都是用于部署Web应用程序的平台,它们各有特点和适用场景:Netlify:Netlify是一个现代化的静态站点部署平台,它提供了简单易用的界面和强大的功能,特别适合部署静态网站、单页面应用和Jamstack应用。Netlify提供了自动构建、部署、CDN加速......
  • day29 回溯算法part5 代码随想录算法训练营 491. 非递减子序列
    题目:491.非递减子序列我的感悟:难不怕,不行就抄一遍,再默写一遍,多记忆几遍。加油!!!理解难点:uset是本层的, res收获的是节点(满足要求的节点),不用return(用了return是仅仅收集叶子节点的)判断的逻辑,是nums[i]当前的节点和目标的path的区别代码示例:classSolution:......
  • 机器学习:公式推导与代码实现 PDF下载
    作为一门应用型学科,机器学习植根于数学理论,落地于代码实现。这就意味着,掌握公式推导和代码编写,方能更加深入地理解机器学习算法的内在逻辑和运行机制。本书在对全部机器学习算法进行分类梳理的基础之上,分别对监督学习单模型、监督学习集成模型、无监督学习模型、概率模型四个大类......
  • 新春快乐跨年烟花代码
    http://www.shanhubei.com/archives/13642.html直接上代码:<!DOCTYPEhtml><htmllang="en"><head><metacharset="UTF-8"><title>2024新年快乐!万事如意!</title><metaname="viewport"content=&qu......