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

生产环境Apex出现System.QueryException非选择性查询异常求助

Salesforce生产环境查询异常排查求助

遇到的异常

System.QueryException: Non-selective query against large object type (more than 1000000 rows). Consider an indexed filter...

触发异常的查询代码(位于触发器处理类)

for (Order_Line_Item__c oli : [SELECT id, Product_Code__c, Stock_Location__c, Contract_Product__r.Product__c FROM Order_Line_Item__c WHERE Contract_Product__c IN :cpIDSet AND Stock_Location__c IN :stockLocationSet AND Status__c = 'Open'])

已尝试的排查方案

  • 使用索引筛选器提升查询选择性
  • 确认查询返回记录数未超出Salesforce governor limits
  • 排查查找数据倾斜问题,确认每个对象的查找数远低于10000

咨询问题

  1. 是否存在明显的问题点?
  2. 如何进一步提升该查询的选择性?
  3. 还有哪些额外的思路或方法可以尝试解决此问题?

异常截图

Salesforce查询异常截图


问题分析与解决方案

1. 明显的问题点

  • 核心问题是查询选择性不足:尽管尝试了索引筛选,但当前过滤条件组合可能无法让Salesforce优化器有效利用索引。尤其当Order_Line_Item__c数据量超100万行时,即便返回记录少,查询扫描范围仍可能过大。
  • 需重点确认:Contract_Product__c、Stock_Location__c、Status__c是否都有有效索引?若Status__c是无自定义索引的文本字段,会拉低整体选择性;另外,若cpIDSet或stockLocationSet包含ID过多(如超200个),IN子句的选择性也会下降。

2. 进一步提升查询选择性的方法

  • 优化索引配置:
    • 给Status__c创建自定义索引,或结合Contract_Product__c/Stock_Location__c创建复合索引,尤其是当Status__c可选值较少时。
    • 检查查找字段的空值占比:若Contract_Product__c或Stock_Location__c存在大量空值,可在查询中添加!= null过滤,提升索引利用率。
  • 缩小过滤范围:
    • 限制cpIDSet和stockLocationSet的大小,避免一次性传入过多ID,必要时拆分查询分批处理。
    • 增加高选择性的额外过滤条件,比如按CreatedDate或LastModifiedDate做范围筛选,进一步缩小扫描范围。
  • 验证查询计划:
    • 使用Salesforce查询计划工具(Query Plan)分析该查询,查看实际命中的索引和扫描行数,确认是否存在索引未被有效利用的情况。

3. 额外思路与方法

  • 分批处理查询:将大集合拆分为小批次(如每次处理100个ID),分批执行查询,降低单次查询的扫描范围。
  • 利用平台缓存:若查询结果短时间内无频繁变化,可将结果存入Platform Cache,避免重复执行相同查询。
  • 检查数据分布:统计Status__c = 'Open'的记录占总数据量的比例,若占比超30%,即便有索引,Salesforce也可能选择全表扫描,此时需结合其他高选择性字段共同过滤。
  • 异步化处理:若触发器同步执行压力大,可将该查询逻辑移至Queueable Apex等异步处理流程,减少同步执行时的资源占用。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.02 16:55:57