function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
JohnDuraiJohnDurai 

System.QueryException: Non-selective query against large object type (more than 200000 rows) - John

Hi All - I am facing the below error for trigger though i have filtered the condition using where clause. is there any best practise or suggestable way that i can finetune/tweak the query here?

Error : System.DmlException: Insert failed. First exception on row 0; first error: CANNOT_INSERT_UPDATE_ACTIVATE_ENTITY, AssetTrigger2: execution of AfterInsert caused by: System.QueryException: Non-selective query against large object type (more than 200000 rows). Consider an indexed filter or contact salesforce.com about custom indexing. Even if a field is indexed a filter might still not be selective when: 1. The filter value includes null (for instance binding with a list that contains null) 2. Data skew exists whereby the number of matching rows is very large (for instance, filtering for a particular foreign key value that occurs many times) Failing Query: SELECT id, OrderId, Package_Definition_Code__c, DISCOCouponCode__c, TotalActiveSubscriptions__c FROM orderitem WHERE (Package_Definition_Code__c = :tmpVar1 AND DISCOCouponCode__c = :tmpVar2) Current Apex position: AssetTrigger2Helper [47,1] Apex stack: Trigger.AssetTrigger2: line 22, column 1 Class.AssetTrigger2Helper.activeSubsCountB2B: line 47, column 1 Trigger.AssetTrigger2: line 22, column 1: []


Syntax:

public static void activeSubsCountB2B( List<Asset> newAssetList,Map<Id,Asset> oldAssetMap) {
       
        Set<String> assetCouponCodes = new Set<String>();
          Set<String> assetPkgDefs = new Set<String>();
        Map<Id, Asset> assetIdAssetMap = new Map<Id, Asset>();
        
        Set<Id> activeAssetIds = new Set<Id>();
        Set<Id> cancelledAssetIds = new Set<Id>();
        
         for (Asset asset : newAssetList) {
            assetCouponCodes.add(asset.Order_Product__r.DISCOCouponCode__c);
            assetPkgDefs.add(asset.Package_Definition_Code__c);    
            assetIdAssetMap.put(asset.Id, asset);
            if (asset.Status.equals('ACTIVE')) {
                activeAssetIds.add(asset.Id);
            } else if (asset.Status.equals('CANCELLED'))  {
                cancelledAssetIds.add(asset.Id);
            } 
        }
        
        Map<String, Set<Asset>> pkdCCAssetsMap = new Map<String, Set<Asset>>();
        for (Asset asset: newAssetList) {
         
            String pkgDefCCKey = asset.Order_Product__r.DISCOCouponCode__c+'-'+ asset.Package_Definition_Code__c;
            Set<Asset> pkdCCAssets =  pkdCCAssetsMap.containsKey(pkgDefCCKey) ? pkdCCAssetsMap.get(pkgDefCCKey) : new Set<Asset>();
            pkdCCAssets.add(asset);
            pkdCCAssetsMap.put(pkgDefCCKey, pkdCCAssets);
        }
        
       List<OrderItem> assetOrderItems =  [select id,OrderId, Package_Definition_Code__c, DISCOCouponCode__c, TotalActiveSubscriptions__c from orderitem where
         Package_Definition_Code__c =: assetPkgDefs and DISCOCouponCode__c =: assetCouponCodes];
        
           Map<Id, OrderItem> assetOrderItemsMap = new Map<Id, OrderItem>();
        Map<Id, OrderItem> updateableOrderItems = new Map<Id, OrderItem>();
        Map<Id, Set<Asset>> orderItemIdAssetsMap = new Map<Id, Set<Asset>>();
        Map<Id, Order> orderMap = new Map<Id, Order>(); 
Sai PraveenSai Praveen (Salesforce Developers) 
Hi John,

Can you run your query with the parameters and check as mentioned in the below article.

https://help.salesforce.com/s/articleView?id=000323572&type=1 (https://help.salesforce.com/s/articleView?id=000323572&type=1)


If this solution helps, Please mark it as best answer.

Thanks,
 
JohnDuraiJohnDurai
I am already running the query by passing parameter in where clause stil hitting exception
Sai PraveenSai Praveen (Salesforce Developers) 
Hi John,

If this is the scenerio , you need to declare any one of the field as External Id with the process I shared you above or need to Raise a case with salesforce with this issue.

If this solution helps, Please mark it as best answer.

Thanks,

 
ravi soniravi soni
hi JohnDurai,
I read your error follow below steps. It may help you.
#1. Make sure assetPkgDefs,assetCouponCodes both variable doesn't null. Add system variable before below query and print both variable value.

List<OrderItem> assetOrderItems =  [select id,OrderId, Package_Definition_Code__c, DISCOCouponCode__c, TotalActiveSubscriptions__c from orderitem where
         Package_Definition_Code__c =: assetPkgDefs and DISCOCouponCode__c =: assetCouponCodes];

#2. If data is coming then add limit in query maybe there are lots of the records is coming so just add limit and just check is it working or not.
try below query.
List<OrderItem> assetOrderItems =  [select id,OrderId, Package_Definition_Code__c, DISCOCouponCode__c, TotalActiveSubscriptions__c from orderitem where
         Package_Definition_Code__c =: assetPkgDefs and DISCOCouponCode__c =: assetCouponCodes limit 1000];



If above steps is helpfull to you, don't forget to mark it as best answer.
thank you