System.QueryException: Non-selective query against large object type (more than 200000 rows). Consider an indexed filter or contact salesforce.com about custom indexing.
What does this error mean?
Salesforce requires queries against large objects (200,000+ records) to be selective — meaning the WHERE clause must filter on an indexed field that narrows results below a system-defined threshold. The threshold is 10% of the first million records, or 5% for records beyond a million, with an absolute ceiling of 333,333 records.
Without a selective filter, Salesforce would perform a full table scan on every query — unacceptable in a multi-tenant environment where one org's inefficient query could impact others. This error is thrown proactively to protect platform performance.
Common Causes
1. Filtering on non-indexed custom fields
Custom fields are not indexed by default. A WHERE Custom_Status__c = 'Active' on a large object forces a full table scan.
2. Using != NULL on any field
Negative filters like WHERE Field__c != null or WHERE Field__c != 'value' are inherently non-selective because they potentially match most records in the table.
3. Trigger queries without ID-based filters
Trigger queries that join to large objects by non-indexed relationship fields rather than primary key IDs.
How to Fix It
Solution 1: Filter on standard indexed fields
Salesforce automatically indexes: Id, Name, OwnerId, CreatedDate, LastModifiedDate, RecordTypeId, and all lookup/master-detail fields. Use these in your WHERE clause.
-- ❌ NON-SELECTIVE — custom field, no index
SELECT Id FROM Case WHERE Custom_Status__c = 'Open'
-- ✅ SELECTIVE — indexed standard field
SELECT Id FROM Case
WHERE CreatedDate = LAST_N_DAYS:30
AND OwnerId = :currentUserId
-- ✅ SELECTIVE — primary key in trigger context
SELECT Id, Status FROM Case
WHERE Id IN :Trigger.newMap.keySet()
Solution 2: Request a custom index from Salesforce
If your business logic requires filtering on a specific custom field, raise a Salesforce Support case requesting a custom index on that field. Custom indexes are free and Salesforce reviews them against selectivity criteria.
Solution 3: Add a skinny table for reporting queries
For complex reporting queries that can't be made selective, ask Salesforce Support about a skinny table — a denormalized read-only copy of frequently queried fields that can speed up otherwise non-selective queries.
Pro Tip: To check which fields are indexed on an object, go to Setup → Object Manager → [Object] → Fields & Relationships. Indexed fields show a checkmark in the Indexed column. Standard lookup fields are always indexed.