You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何获取数据库首个空闲Device Type Id的第二种代码更优?

两种获取空闲Device Type Id实现的优势对比

需求背景

在预定义的ID范围(如10-20)内,从数据库中获取首个未被使用的Device Type Id。例如现有ID列表为[1,2,4,10,11,12,14],范围10-20时需返回13。

两种实现代码

第一种实现

firstFreeId = Enumerable.Range(_idRangeFrom.Value + 1, _idRangeTo.Value).First(i => !_dbContext.DeviceTypes.Any(dt => dt.DeviceTypeId == i));

第二种实现

var deviceTypeIds = _dbContext.DeviceTypes.Where(e => e.DeviceTypeId > _idRangeFrom.Value && e.DeviceTypeId < _idRangeTo.Value).Select(e => e.DeviceTypeId);
firstFreeId = Enumerable.Range(_idRangeFrom.Value + 1, _idRangeTo.Value).First(i => !deviceTypeIds.Any(dtId => dtId == i));

(注:_idRangeFrom和_idRangeTo为预定义范围,_dbContext.DeviceTypes是EF对应数据库的DeviceTypes表上下文)

第二种实现的核心优势

  • 数据库查询次数大幅减少
    第一种实现会对Enumerable.Range生成的每个ID发起单独的数据库查询(Any(dt => dt.DeviceTypeId == i)),如果范围跨度大,会产生数十甚至上百次数据库请求。而第二种实现仅执行一次范围查询,把目标区间内已存在的所有ID一次性拉取到内存,后续判断全在内存中完成,仅需1次数据库请求,极大降低了网络连接和数据库交互的开销。

  • 降低数据库负载
    多次小查询会频繁占用数据库连接,增加CPU与IO消耗;单次范围查询能更好地利用数据库查询优化器,尤其当DeviceTypeId有索引时,范围扫描的效率远高于多次单值匹配查询。

  • 缩短数据库交互窗口
    虽然两种实现都存在并发场景下的竞态风险(比如查询到空闲ID后被其他线程抢先占用),但第二种实现的数据库操作时间更短,一定程度上降低了这类问题的发生概率。

  • 内存判断效率更高
    把目标区间内的已用ID加载到内存后,后续的Any判断是纯内存操作,相比第一种每次都要走网络请求到数据库,响应速度提升明显,尤其是当范围内已用ID数量不多时,优势更突出。


内容的提问来源于stack exchange,提问作者Standej

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.31 15:05:43