SqlSugar实战:解锁高效数据库操作的五大核心技巧

张开发
2026/6/26 18:48:26 15 分钟阅读
SqlSugar实战:解锁高效数据库操作的五大核心技巧
1. 批量操作的艺术告别低效循环SqlSugar的批量操作功能绝对是处理海量数据时的救星。还记得我刚入行时傻乎乎地用foreach循环插入1000条数据足足花了3秒多现在用SqlSugar的批量插入同样的数据量只需要63毫秒性能提升近50倍三种批量插入方式各有千秋参数化分页插入适合小批量高频操作比如电商系统的订单明细插入。我实测过500条以内的数据用这种方式最稳底层会智能利用执行计划缓存。// 推荐场景订单支付后的明细记录 await db.Insertable(orderDetails).UseParameter().ExecuteCommandAsync();万金油写法1万条数据以内的通用选择。去年做物流系统时我用这种方式处理运单数据6000条记录只用了200ms内存占用也很友好。// 典型应用物流运单批量导入 await db.Insertable(waybills).ExecuteCommandAsync();BulkCopy黑科技超过10万条数据时的终极武器。有个客户需要导入历史数据我用这个功能处理了120万条记录比传统方式快30%。但要注意MySQL需要配置AllowLoadLocalInfiletrue。// 百万级数据迁移方案 await db.FastestHistoryData() .PageSize(100000) .BulkCopyAsync(historicalRecords);避坑指南批量更新时一定要控制PageSize我建议设置在500-2000之间。上周有个同事设成50000导致内存溢出Oracle环境下使用BulkCopy需要额外配置序列这点官方文档没强调我踩过坑批量操作建议包裹事务特别是金融类业务避免部分失败导致数据不一致2. 联表更新的高阶玩法联表更新是复杂业务场景的刚需功能。比如最近做的CRM系统需要同时更新客户表和订单表的状态SqlSugar的联表更新让这个需求变得异常简单。两种经典实现方式子查询式跨数据库兼容性最好。我在多租户项目中就用这种方式一套代码兼容MySQL和SQL Server。// 多平台兼容方案 db.UpdateableOrder() .SetColumns(o new Order { Status SqlFunc.SubqueryableCustomer() .Where(c c.Id o.CustomerId) .Select(c c.VipLevel) }) .ExecuteCommand();Join式语法最优雅但要注意Oracle/达梦只支持两表关联。做电商促销系统时我用这种写法同时更新商品表和库存表。// 电商系统经典案例 db.UpdateableProduct() .InnerJoinInventory((p,i) p.SKU i.SKU) .SetColumns((p,i) new Product { Price p.Price * 0.8, Stock i.Quantity }) .Where((p,i) p.Category 双十一促销) .ExecuteCommand();性能优化心得联表更新前先建好索引特别是关联字段。有次性能调优加了索引后速度提升8倍大数据量联表更新建议分批次进行我通常每批处理5000条复杂联表更新可以先输出SQL检查执行计划用ToSqlString()方法就能看到生成的SQL3. 分页处理的性能玄机分页查询看似简单但隐藏着很多性能陷阱。去年我们的工单系统就因为分页问题差点崩掉后来用SqlSugar的分页优化方案完美解决。智能分页三件套基础分页适合简单列表。注意PageNumber是从1开始的这个设计反人类但必须遵守。// 工单列表分页 var page db.QueryableWorkOrder() .Where(o o.Status 处理中) .ToPageList(pageNumber, pageSize, ref total);内存分页当需要先加工数据再分页时使用。做报表系统时经常用这个模式。// 先过滤再分页的报表查询 var query db.QueryableSalesRecord() .Where(r r.Year 2023) .ToList() // 先加载到内存 .Skip((pageNumber-1)*pageSize) .Take(pageSize);大数据分页百万级数据时的解决方案。用With语法可以避免深分页性能问题。// 千万级用户列表优化方案 var result db.QueryableUser() .With(SqlWith.NoLock) .Where(u u.IsActive) .Select(u new { u.Id, u.Name }) .ToPageList(pageNumber, pageSize);血泪教训千万避免OrderBy非索引字段分页有次生产事故就是这么引发的分页大小不要超过1000前端可以做成加载更多模式分布式环境下的分页要特别注意最好用唯一键排序4. 实体操作的智能特性SqlSugar的实体操作有很多隐藏技巧这些正是它比Dapper等微ORM强大的地方。四个必知特性动态表名做多租户系统时特别有用。我们公司SaaS产品就用这个功能实现分表存储。// 根据租户动态切换表名 db.Insertable(user) .AS($Tenant_{tenantId}_Users) .ExecuteCommand();差异更新只更新修改过的字段。审计系统必备功能可以记录字段级变更。// 智能跟踪变更 var user db.QueryableUser().First(); db.Tracking(user); // 开始跟踪 user.Name 新名字; db.Updateable(user).ExecuteCommand(); // 只更新Name字段乐观并发防止更新冲突。电商库存系统就靠这个避免超卖。// 带版本控制的更新 db.Updateable(product) .UpdateColumns(p new { p.Stock }) .Where(p p.Version originalVersion) .ExecuteCommand();JSON支持处理复杂字段的神器。我们用这个存储产品的动态属性。// 存储JSON数据 [SugarColumn(IsJson true)] public Dictionarystring,object ExtendedInfo {get;set;}实用技巧用IgnoreColumns忽略大字段查询比如文章内容这种复杂查询可以用Mapper方法实现延迟加载事务操作建议用Ado直接执行SQL性能更好5. 查询构造器的魔法SqlSugar的查询构造器是我用过最流畅的LINQ实现比EF Core的语法更符合国人习惯。五大实用模式多条件动态查询配合Expression实现灵活筛选。权限系统必备技能。// 动态构建查询条件 ExpressionFuncUser, bool expr u true; if(!string.IsNullOrEmpty(name)) expr expr.And(u u.Name.Contains(name)); if(roleId.HasValue) expr expr.And(u u.RoleId roleId); var users db.QueryableUser().Where(expr).ToList();多表导航属性比Join更直观的关联查询。ERP系统里经常用。// 导航属性自动关联 [SugarColumn(IsIgnore true)] public ListOrder Orders { get; set; } var customers db.QueryableCustomer() .Includes(c c.Orders) .ToList();SQL函数支持直接调用数据库原生函数。做数据分析时特别有用。// 使用MySQL的DATE_FORMAT函数 db.QueryableOrder() .Select(o new { Date SqlFunc.DateFormat(o.CreateTime,%Y-%m), Total SqlFunc.AggregateSum(o.Amount) }) .GroupBy(o SqlFunc.DateFormat(o.CreateTime,%Y-%m)) .ToList();存储过程调用兼容传统架构。银行项目经常需要这个。// 调用存储过程 var parameters new ListSugarParameter { new SugarParameter(userId, 123) }; db.Ado.UseStoredProcedure().GetDataTable(sp_GetUserOrders, parameters);全局过滤器自动附加查询条件。多租户系统的基石。// 自动过滤已删除数据 db.QueryFilter.Add(new TableFilterItemUser(it it.IsDeleted false));特别提醒复杂查询建议先用ToSql()输出SQL检查循环内避免频繁创建Queryable对象分库分表场景要特别注意查询路由

更多文章