Salesforce:获取选择性查询的“非选择性查询”错误

Salesforce:获取选择性查询的“非选择性查询”错误,salesforce,soql,Salesforce,Soql,我正在运行一个非常简单的SOQL查询,我已经重命名了对象,并将其包含在这里: List <ObjectA__c> allRecords= [ select name, Id,Contact__c,... from ObjectA__c where Contact__c IN (SELECT Contact__c FROM ObjectB__c WHERE id IN :idList) ]; ObjectB只有300条记录,objectA有超过200k条记录,所以很明显是这个对象

我正在运行一个非常简单的SOQL查询,我已经重命名了对象,并将其包含在这里:

List <ObjectA__c> allRecords= [
select name, Id,Contact__c,...
from ObjectA__c
where Contact__c IN 
(SELECT Contact__c FROM ObjectB__c WHERE id IN :idList) 
];
ObjectB只有300条记录,objectA有超过200k条记录,所以很明显是这个对象造成了问题

显然,id是索引的,objectB的联系人字段是一个主详细信息,所以它也是索引的,并且不能包含null

我愿意接受任何可能有帮助的建议。故障排除仅在idList基于trigger.new构建的导入中产生此错误,并且在anon apex中手动运行代码运行正常,没有问题


我已经没有什么可以尝试的了,所以我欢迎你的建议。

我喜欢那些对问题投否决票而不评论他们认为可以改进的地方的人

一些一般阅读材料:

一般来说,你应该考虑的事实是,优化这个查询现在可能会对你产生长期影响。如果使用了ObjectB的正确组合,您将达到50K查询行的限制,事务将回滚。更不用说,用户手动插入一条与流行联系人的记录将永远等待简单的保存完成。。。两个想法:

分块并卸载到@future call 或者提交一个可以更轻松地处理此类工作负载的批处理作业 或者减少导入的批量大小 就你的情况而言,要么我没有正确地理解这个问题,要么你把它复杂化了

从ObjectB\uu c中选择Contact\uu c,其中id位于:idList

idList是根据trigger.new构建的

另外,我假设它发生在插入后在ObjectB_u_uCafter上触发一些东西

您在trigger.new中已经有了所有ObjectB_;c记录。不需要查询他们&他们的联系人

所以如果你要收集所有的联系人ID

Set<Id> contactIds = new Set<Id>();
for(ObjectB__c b : trigger.new){
    contactIds.add(b.Contact__c);
}
contactIds.remove(null);
System.debug(contactIds);

如果这一项仍然对您无效,并且您无法对其进行更多过滤,也无法减少批处理大小-是的,异步处理时间@未来或批处理作业。

除了eyescream的建议之外,您可以尝试新的。这将向您展示Salesforce如何在不实际运行查询的情况下执行查询

链接的文章有一个Visualforce页面和相关的Apex控制器,您可以使用它来形成这些REST查询。或者你也可以使用Expose获得相同的信息,我目前在FuseIT工作。这是开发人员的免费工具


所以我想与大家分享一下,我刚刚了解到,不能用非选择性查询来查询一个记录超过100000条的对象,只能在触发器中进行查询,除非是从触发器调用,否则不能使用anon-apex或其他被调用类的方法。我将我的代码放入触发器,并能够导致它失败,所以现在我能够进行故障排除并制定解决方案。
SELECT Id, Name, Contact__c
FROM ObjectA__c
WHERE Contact__c IN :contactIds