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
Rajiv B 3Rajiv B 3 

caused by: System.QueryException: Non-selective query

Hi all , 
I am getting below error while change the Storage__C owner from X to Y. 
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.

 
trigger StevContacts on Storage__C (after update) 
{
    
    List<Storage__C> Strs = [select Id, Type, (select Primary_Campaign__c from Contacts) from Storage__C where Id IN :Trigger.newMap.keySet()];
    List<Contact> contacts = new List<Contact>();
    Storage__C oldStrs;

    for(Storage__C s: Strs)
    {
        oldStrs = Trigger.oldMap.get(s.Id);
      
        if (oldStrs.Type != s.Type && s.Type == 'Stev')
        {       
            for(Contact c: s.Contacts)
            {
                c.Primary_Campaign__c='Stev';
                contacts.add(c);
            } 
        }
        else if (oldStrs.Type != s.Type && oldStrs.Type == 'Stev')
        {  
            for(Contact c: s.Contacts)
            {
                c.Primary_Campaign__c='ting';
                contacts.add(c);
            } 
        }
    update contacts;
    }
}
I have gone through documents . Found below below points  but not able fiqure it out .. where exactly i have to do changes in my code. 

Options to resolve error
1. You may find that the query in question needs to be more selective in the WHERE clause. According to the Salesforce standards & best practices - the where clause needs to subset 10% or less of the data.
2. A custom index on the field.
3. A possible quick fix may be to make the field in question an external ID. Since external IDs are indexed automatically, this will create the index and may solve the problem.

Appreciate your help 
Naveen Kumar B H(bhns)Naveen Kumar B H(bhns)
Hi Rajiv,

Change your code with below code before making any other changes. Don't forget to replace proper API name for fields.
 
trigger StevContacts on Storage__C (after update)
{
    List<Contact> contacts = new List<Contact>();
	Map<Id,List<Contact>> storageIdContactMap = new Map<Id,List<Contact>>(); //idis nothing but parent field in contact object. i assume Storage__C is the lookup field. 
	for(Contact c : [SELECT ID,Primary_Campaign__c,Storage__C from Contact WHERE Storage__C IN : Trigger.newMap.keySet()]){
		if(!storageIdContactMap.isEmpty() && storageIdContactMap.containsKey(Storage__C) && storageIdContactMap.get(Storage__C) != null){
			storageIdContactMap.get(Storage__C).add(c);
		}else{
			storageIdContactMap.put(Storage__C, new Contact{c});
		}
	}
	for(Storage__C s: Trigger.New){
		if(Trigger.oldMap.get(s.Id) != s.Type && s.Type == 'Stev'){
			if(storageIdContactMap.contains(s)){
				for(Contact c: storageIdContactMap.get(s)){
					c.Primary_Campaign__c='Stev';
					contacts.add(c);
				} 
			}
		}else if (oldStrs.Type != s.Type && oldStrs.Type == 'ting'){  
			if(storageIdContactMap.contains(s)){
				for(Contact c: storageIdContactMap.get(s)){
					c.Primary_Campaign__c='ting';
					contacts.add(c);
				} 
			}
		}
	}
}

Let me know if you face any other issues.

Regards
Naveen